#include "mainwindow.h"
#include "configmanager.h"
#include "customfilebrowser.h"
#include "minimalmemorymanager.h"
#include "unifiedthreadmanager.h"
#include "statusbarinfo.h"
#include "IconFactory.h"
#include "applicationstatemanager.h"
#include "unifiedthreadmanager.h"
#include "fileprocessingtask.h"
#include "memorycachemanager.h"
#include <QPrinter>
#include <QPainter>
#include <QPainterPath>
#include <QtGui/QPdfWriter>
#include <QFileDialog>
#include <QMessageBox>
#include <QSettings>
#include <QScreen>
#include <QTimer>
#include <QCloseEvent>
#include <QProgressDialog>
#include <QPrintDialog>
#include <QApplication>
#include <QPointer>
#include <QTranslator>
#include <QScrollBar>
#include <QShortcut>
#include <QDateTime>
#include <QDir>
#include <QStandardPaths>
#include "pathmanager.h"
#include <QDesktopServices>
#include <QUrl>
#include "progressdialog.h"
#include "systemconfigdialog.h"
#include "updatechecker.h"
#include <QProcess>
#include "licensemanager.h"
#include "configimpactdetector.h"
#include "unifiedfileinfo.h"
#include "watermark.h"
#include "licensedialog.h"
#include "nextgen_placeholder.h"
#include "dpiservice.h"
#include "toastnotification.h"
#include "logindialog.h"
#include "protection.h"
#include "codeobfuscation.h"
#include "advancedprotection.h"
#include "dynamicwatermark.h"
#include "util.h"
// 旧的静态成员变量定义已移除，现在使用配置驱动的方法
#include "fileprocessworker.h"
#include <QInputDialog>
#include <QThread>
#include <QThreadPool>
#include <QImageReader>
#include <QTextEdit>
#include <QFile>
#include <QDir>
#include <QDateTime>
#ifdef POPPLER_AVAILABLE
#include <cpp/poppler-document.h>
#include <cpp/poppler-page.h>
#include <cpp/poppler-page-renderer.h>
#include <cpp/poppler-image.h>
#endif
// 统一导航服务实现（当前复用既有的内部处理逻辑）
void MainWindow::navigateAndHighlight(int thumbnailIndex, NavigationIntent intent)
{
    Q_UNUSED(intent);
    handleThumbnailClickInternal(thumbnailIndex);
}
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , m_translator(nullptr)
    , m_updateChecker(nullptr)
    , m_hasUpdateAvailable(false)
    , m_mainToolBar(nullptr)
    , m_logStream(nullptr)
    , m_pdfDocument(nullptr)
    , m_pdfPageCount(0)
    , m_cacheManager(UnifiedCacheManager::instance())
    , m_statusBarManager(nullptr)
    , m_streamingExportManager(nullptr)  // 流式导出管理器
    , m_marginUpdateTimer(nullptr)
{
    clearLogsOnStartup();
    // 设置主窗口背景为淡灰色
    setStyleSheet("QMainWindow { background-color: #f5f5f5; }");
    // 使用调色板方法作为备用
    QPalette palette = this->palette();
    palette.setColor(QPalette::Window, QColor(245, 245, 245));
    setPalette(palette);
    // 日志关闭，不初始化日志文件
    // 初始化缓存管理器
    // 在setupUI之前加载上次使用的语言
    QString savedLanguage = ConfigManager::getLanguage();
    loadLanguage(savedLanguage);
    m_currentLanguage = savedLanguage;
    // === 重构：加载系统配置 ===
    // Martin Fowler: Initialize Configuration Early
    loadSystemConfig();
    // 初始化统一页面渲染器（在setupUI之前，因为statusBar需要用到）
    m_unifiedRenderer = new UnifiedPageRenderer(this);
    // 设置默认处理设置
    m_processingSettings = ProcessingSettings::getPreset("标准文档");
    m_unifiedRenderer->setRenderSettings(m_processingSettings);
    // Martin Fowler重构：依赖注入 - 将ProcessingSettings注入到DpiService
    DpiSvc.setProcessingSettings(&m_processingSettings);
// 先设置固定窗口布局，再创建UI组件
    setupFixedWindowLayout();
    setupUI();
    // 将统一渲染器设置到PageView（在setupUI之后）
    if (m_pageView) {
        m_pageView->setUnifiedRenderer(m_unifiedRenderer);
    }
    // === Martin Fowler重构：全局页码管理器信号连接 ===
    GlobalPageManager& globalPageManager = GlobalPageManager::instance();
    connect(&globalPageManager, &GlobalPageManager::globalPageChanged,
            this, &MainWindow::onGlobalPageChanged);
    connect(&globalPageManager, &GlobalPageManager::pageMappingsChanged,
            this, &MainWindow::onPageMappingsChanged);
    connect(&globalPageManager, &GlobalPageManager::totalGlobalPagesChanged,
            this, &MainWindow::onTotalDisplayPagesChanged);
    // 智能刷新机制：不再需要防抖定时器
    // 初始化磁盘缓存管理器
    m_cacheManager = UnifiedCacheManager::instance();
    loadCacheSettings();
    // 旧的UpdateChecker已被UpdateManager替代
    createActions();
    createMenus();
    createToolBar();
    // 不再加载窗口状态，使用固定布局
    loadSettings();
    // 不再管理侧边栏状态
    
    // 设置窗口标题
    setWindowTitle(tr("LimeReader - 影谷长图处理大师"));
    
    // 标记初始化完成
    m_initializationComplete = true;

    // === 初始化安全防护系统 ===
    initializeSecuritySystems();

    // 初始化登录状态
    initializeLoginStatus();

    // 初始化版本信息
    initializeVersionInfo();

    // 初始化API管理器（使用单例）
    m_apiManager = ApiManager::instance();
    connect(m_apiManager, &ApiManager::versionInfoReceived, this, &MainWindow::onVersionInfoReceived);

    // 连接心跳和认证错误处理信号
    connect(m_apiManager, &ApiManager::tokenExpired, this, &MainWindow::onTokenExpired);
    connect(m_apiManager, &ApiManager::heartbeatError, this, &MainWindow::onHeartbeatError);
    connect(m_apiManager, &ApiManager::heartbeatSuccess, this, &MainWindow::onHeartbeatSuccess);
    connect(m_apiManager, &ApiManager::deviceNotFound, this, &MainWindow::onDeviceNotFound);
    connect(m_apiManager, &ApiManager::networkError, this, &MainWindow::onNetworkError);

    // 初始化更新管理器
    m_updateManager = new UpdateManager(this);
    connect(m_updateManager, &UpdateManager::updateAvailable, this, &MainWindow::onUpdateAvailable);
    connect(m_updateManager, &UpdateManager::downloadFinished, this, &MainWindow::onUpdateFinished);
    connect(m_updateManager, &UpdateManager::downloadError, this, &MainWindow::handleUpdateError);
    connect(m_updateManager, &UpdateManager::downloadProgress, this, &MainWindow::onUpdateProgress);
    connect(m_updateManager, &UpdateManager::serverVersionReceived, this, [this](const QString& version) {
        m_serverVersion = version;
        updateVersionDisplay();
        updateWelcomeMessage();
    });

    // 初始化独立的更新检查器 - 用于About窗口等独立场景
    m_updateChecker = new UpdateChecker(this);

    // 连接UpdateChecker信号到MainWindow（全局更新提示）
    connect(m_updateChecker, &UpdateChecker::updateAvailable, this,
            [this](const QString& version, const QString& downloadUrl, const QString& releaseNotes, const QString& md5, const QString& fileSize) {

        // 存储完整的更新信息到成员变量
        m_serverVersion = version;
        m_downloadUrl = downloadUrl;
        m_releaseNotes = releaseNotes;
        m_md5Hash = md5;
        m_fileSize = fileSize;
        m_hasUpdateAvailable = true;


        // 构建兼容VersionManager::UpdateInfo格式的更新信息
        VersionManager::UpdateInfo updateInfo;
        updateInfo.latestVersion = VersionManager::Version::fromString(version);
        updateInfo.currentVersion = VersionManager::Version::fromString(m_currentVersion);
        updateInfo.updateUrl = downloadUrl;
        updateInfo.updateLog = releaseNotes;
        updateInfo.updateSize = fileSize;
        updateInfo.checksumMD5 = md5;
        updateInfo.forceUpdate = false; // UpdateChecker API中没有强制更新标识
        updateInfo.hasUpdate = true;

        onUpdateAvailable(updateInfo);
    });

    connect(m_updateChecker, &UpdateChecker::checkError, this,
            [this](const QString& error) {
        // 可以在状态栏显示错误信息
        if (statusBar()) {
            statusBar()->showMessage(tr("更新检查失败: %1").arg(error), 5000);
        }
    });

    connect(m_updateChecker, &UpdateChecker::noUpdateAvailable, this,
            [this]() {
        // 可以在状态栏显示信息
        if (statusBar()) {
            statusBar()->showMessage(tr("当前已是最新版本"), 3000);
        }
    });

    // 初始化系统托盘管理器
    m_systemTrayManager = new SystemTrayManager(this);
    m_systemTrayManager->setMainWindow(this);
    m_systemTrayManager->initialize();
    if (m_systemTrayManager->isSystemTrayAvailable()) {
        m_systemTrayManager->show();
    } else {
    }

    // 用户信息对话框将在点击登录按钮时创建，不需要预初始化
    m_userInfoDialog = nullptr;

    // 不设置默认布局模式，让文件加载时从统一状态管理器获取
    // 注册为统一线程管理器的进度观察者
    UnifiedThreadManager::instance()->addProgressObserver(this);
    // createLanguageMenu();  // 暂时隐藏语言菜单
    // Extract Class重构：初始化页面渲染器
    m_pageRenderer = new PageRenderer(this);
    // Martin Fowler Extract Class重构：初始化统一拖拽处理器
    m_dragDropHandler = new UnifiedDragDropHandler(this, this);
    setAcceptDrops(true); // 启用接收拖放

    // 设置事件过滤器来检测用户活动
    installEventFilter(this);

    // 注释：移除独立的UpdateChecker检查，统一使用ApiManager心跳检查
}
MainWindow::~MainWindow()
{
    // 移除进度观察者
    UnifiedThreadManager::instance()->removeProgressObserver(this);
    if (m_translator) {
        delete m_translator;
    }
    // 清理PDF文档
    if (m_pdfDocument) {
        delete m_pdfDocument;
        m_pdfDocument = nullptr;
    }
    // 清理日志文件
    if (m_logStream) {
        delete m_logStream;
        m_logStream = nullptr;
    }
    // 清理用户信息对话框
    if (m_userInfoDialog) {
        delete m_userInfoDialog;
        m_userInfoDialog = nullptr;
    }
}
void MainWindow::closeEvent(QCloseEvent *event)
{
    // 显式关闭所有停靠窗口，特别是浮动的停靠窗口
    if (m_fileBrowserDock) {
        m_fileBrowserDock->close();
    }
    if (m_thumbnailDock) {
        m_thumbnailDock->close();
    }
    // 保存设置
    saveSettings();
    // 确保所有子窗口都被关闭
    QList<QWidget*> topLevelWidgets = QApplication::topLevelWidgets();
    for (QWidget* widget : topLevelWidgets) {
        if (widget != this && widget->isVisible()) {
            widget->close();
        }
    }
    // 接受关闭事件
    event->accept();
    // 确保应用程序退出
    QApplication::quit();
}
void MainWindow::setupUI()
{
    // 创建主内容区域（PageView）
    m_pageView = new PageView(this);
    // 设置PageView为主窗口的中央部件
    setCentralWidget(m_pageView);
    // 确保中央部件没有最小尺寸限制，允许dock widget缩小
    m_pageView->setMinimumSize(0, 0);
    // 创建文件列表停靠窗口
    m_fileBrowser = new CustomFileBrowser(this);
    m_fileBrowserDock = new QDockWidget(tr("文件列表"), this);
    m_fileBrowserDock->setObjectName("fileBrowserDock");  // 设置objectName
    m_fileBrowserDock->setWidget(m_fileBrowser);
    m_fileBrowserDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    m_fileBrowserDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);
    // 设置停靠窗口样式，使用微妙的层次感背景色
    m_fileBrowserDock->setStyleSheet(
        "QDockWidget { "
        "    border: none; "
        "    background-color: #f0f0f0; "
        "} "
        "QDockWidget::title { "
        "    text-align: left; "
        "    background: #f0f0f0; "
        "    padding-left: 8px; "
        "    padding-top: 3px; "
        "    padding-bottom: 3px; "
        "} "
        "QDockWidget > QWidget { "
        "    margin: 0px; "
        "    padding: 0px; "
        "    border: none; "
        "    background-color: #f0f0f0; "
        "}"
    );
    m_fileBrowserDock->hide(); // 默认隐藏
    addDockWidget(Qt::LeftDockWidgetArea, m_fileBrowserDock);
    
    // 设置dock区域的尺寸策略，确保dock区域能够正确响应尺寸变化
    // 这解决了dock区域背景不跟随缩小的问题
    setDockNestingEnabled(true);  // 启用dock嵌套，允许更灵活的布局
    
    // 宽度保存通过visibilityChanged信号和程序关闭时处理
    
    // 创建右侧标签化面板
    m_virtualThumbnailView = new VirtualThumbnailView(this);
    m_settingsWidget = new SettingsWidget(this);
    m_rightTabs = new QTabWidget();
    m_rightTabs->setMaximumWidth(220);
    // 添加标签页，使用自绘图标
    m_rightTabs->addTab(m_virtualThumbnailView, createNavigationIcon(), "导航");
    m_rightTabs->addTab(m_settingsWidget, createSettingsIcon(), "设置");
    // 最简单的固定宽度样式，减少标签高度
    m_rightTabs->setStyleSheet(
        "QTabWidget::pane { border: 1px solid #ccc; }"
        "QTabBar::tab { "
        "    width: 90px; "
        "    padding: 3px 8px; "  // 进一步减少垂直padding
        "    font-size: 11px; "   // 减少字体大小
        "    height: 20px; "      // 进一步减少标签高度
        "    max-height: 20px; "  // 强制最大高度
        "    min-height: 20px; "  // 强制最小高度
        "    background: #d0d0d0; " // 未选中状态：使用原来的悬停颜色
        "}"
        "QTabBar::tab:selected { "
        "    background: #f0f0f0; " // 选中状态：亮灰色
        "    padding: 3px 8px; "
        "}"
    );
    m_thumbnailDock = new QDockWidget(tr("预览面板"), this);
    m_thumbnailDock->setObjectName("thumbnailDock");  // 设置objectName
    m_thumbnailDock->setWidget(m_rightTabs);
    m_thumbnailDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
    m_thumbnailDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);
    
    // 设置缩略图停靠窗口样式，完全移除阴影效果
    m_thumbnailDock->setStyleSheet(
        "QDockWidget { "
        "    border: none; "
        "    background-color: palette(window); "
        "    box-shadow: none; "
        "} "
        "QDockWidget::title { "
        "    text-align: left; "
        "    background: palette(window); "
        "    padding-left: 8px; "
        "    padding-top: 3px; "
        "    padding-bottom: 3px; "
        "    border: none; "
        "    box-shadow: none; "
        "} "
        "QDockWidget > QWidget { "
        "    margin: 0px; "
        "    padding: 0px; "
        "    border: none; "
        "    background-color: palette(window); "
        "    box-shadow: none; "
        "}"
    );
    
    // 设置缩略图dock widget的尺寸策略，确保能够正确响应尺寸变化
    m_thumbnailDock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
    
    m_thumbnailDock->hide(); // 默认隐藏
    addDockWidget(Qt::RightDockWidgetArea, m_thumbnailDock);

    // 连接虚拟滚动缩略图组件信号
    connect(m_virtualThumbnailView, &VirtualThumbnailView::thumbnailSelected, 
            this, &MainWindow::onThumbnailSelected);
    connect(m_virtualThumbnailView, &VirtualThumbnailView::thumbnailClicked, 
            this, &MainWindow::onThumbnailClicked);
    connect(m_virtualThumbnailView, &VirtualThumbnailView::thumbnailProgressivelyLoaded,
            this, [this](int index) {
                // 文件处理中时，不触发任何可能影响主图的操作
                if (!m_isFileProcessing) {
                    // 可以在这里添加额外的UI反馈，比如进度提示
                }
            });
    // 连接设置面板信号
    connect(m_settingsWidget, &SettingsWidget::settingsChanged,
            this, [this](const ProcessingSettings& settings) {

                // 第一步：更新MainWindow内部状态
                m_processingSettings = settings;

                // 第二步：更新UnifiedPageRenderer（PageView的数据源）
                if (m_unifiedRenderer) {
                    m_unifiedRenderer->setRenderSettings(settings);
                }

                // 第三步：更新SmartPageNumberSelector的页码设置（不涉及边距）
                if (auto* smartSelector = m_settingsWidget->getSmartPageNumberSelector()) {
                    smartSelector->setProcessingSettings(settings);
                }

                // 第四步：智能更新当前可见页面
                // 只更新当前显示的页面，保持懒加载机制完整
                if (!m_currentFileHash.isEmpty() && m_pageView && !m_pages.isEmpty()) {
                    
                    // 获取当前可见页面范围
                    int currentPage = m_pageView->currentPage();
                    int visibleRange = 1; // 更新当前页及前后1页，共3页
                    int startPage = qMax(0, currentPage - visibleRange);
                    int endPage = qMin(m_pages.size() - 1, currentPage + visibleRange);
                    
                    
                    // 启动延迟更新，避免频繁刷新
                    if (m_marginUpdateTimer) {
                        m_marginUpdateTimer->stop();
                    } else {
                        m_marginUpdateTimer = new QTimer(this);
                        m_marginUpdateTimer->setSingleShot(true);
                    }
                    
                    m_marginUpdateTimer->setInterval(300);
                    connect(m_marginUpdateTimer, &QTimer::timeout, this, [this, startPage, endPage]() {
                        
                        // 获取原始页面数量
                        int totalOriginalPages = 0;
                        if (m_currentFileHash.endsWith(".pdf") && m_pdfDocument) {
                            totalOriginalPages = m_pdfPageCount;
                        } else if (m_fileBrowser) {
                            int fileIndex = m_fileBrowser->getCurrentIndex();
                            if (fileIndex >= 0) {
                                QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
                                if (fileIndex < files.size()) {
                                    totalOriginalPages = files.at(fileIndex).pageCount;
                                }
                            }
                        }
                        
                        if (totalOriginalPages > 0) {
                            // 重新加载原始页面
                            QList<QImage> originalPages;
                            for (int i = 0; i < totalOriginalPages; ++i) {
                                QImage page = m_cacheManager->loadFromCache(m_currentFileHash, i);
                                if (!page.isNull()) {
                                    originalPages.append(page);
                                } else {
                                    originalPages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中..."));
                                }
                            }
                            
                            // 重新生成指定范围的组合页
                            auto newLayout = m_unifiedRenderer->rearrangePagesForColumns(originalPages, m_currentMode);
                            
                            // 只更新指定范围的页面
                            for (int i = startPage; i <= endPage && i < newLayout.size() && i < m_pages.size(); ++i) {
                                m_pages[i] = newLayout[i];
                                m_pageView->updatePageContent(i, newLayout[i]);
                            }
                            
                        }
                    });
                    
                    m_marginUpdateTimer->start();
                }

                // 第五步：边距变化通过UnifiedPageRenderer设置自动生效
                // 新生成的页面会使用新的边距设置，无需手动触发更新

                // Martin Fowler重构：Dependency Injection - 更新ImageProcessor DPI配置
                updateImageProcessorDpiConfig();
                // 同步DPI服务的ProcessingSettings，确保DpiSvc读取到最新面板DPI
                DpiSvc.setProcessingSettings(&m_processingSettings);

                // WYSIWYG预览：如面板DPI高于缓存DPI，预览将发生上采样 -> 提示用户
                double systemDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::CacheGeneration);
                double panelDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::WindowRendering);
                if (panelDpi > systemDpi) {
                    QString msg = QString(
                        "输出DPI(%1)高于缓存DPI(%2)\n建议提高系统DPI重建缓存")
                        .arg(panelDpi, 0, 'f', 0)
                        .arg(systemDpi, 0, 'f', 0);
                    ToastNotification::showWarning(this, msg, 6000);
                }

                // 处理起始页码变化
                GlobalPageManager& globalPageManager = GlobalPageManager::instance();
                int newStartOffset = settings.pageNumber.startNumber;
                if (globalPageManager.getPageNumberStartOffset() != newStartOffset) {
                    globalPageManager.setPageNumberStartOffset(newStartOffset);
                }

                // 保存设置到配置文件
                
                ConfigManager::setProcessingSettings(settings.toJsonString());

            });
    // Martin Fowler重构：简化页码更新机制
    // 移除复杂的定时器机制，采用直接更新方式
    if (auto* smartSelector = m_settingsWidget->getSmartPageNumberSelector()) {
        connect(smartSelector, &SmartPageNumberSelector::pagePositionPreviewChanged,
                this, &MainWindow::onPageNumberPositionPreviewChanged);
        // 移除SmartPageNumberSelector的settingsChanged连接，避免重复信号
        // connect(smartSelector, &SmartPageNumberSelector::settingsChanged,
        //         this, &MainWindow::onPageNumberSettingsChanged);
        
        // 连接预设位置变化信号
        connect(m_settingsWidget, &SettingsWidget::pageNumberPositionChanged,
                this, [this](const ProcessingSettings::PageNumberSettings& settings) {
                    // 应用预设位置设置
                    m_processingSettings.pageNumber = settings;
                    if (m_unifiedRenderer) {
                        m_unifiedRenderer->setRenderSettings(m_processingSettings);
                    }
                    // 直接更新页码，不使用定时器
                    if (m_pageView) {
                        m_pageView->forceUpdatePageNumbers();
                    }
                });
    }
    // 连接缩略图动态加载请求信号
    connect(m_virtualThumbnailView, &VirtualThumbnailView::needMoreThumbnails,
            this, &MainWindow::onNeedMoreThumbnails);
    // 保留传统缩略图组件作为备用（暂时隐藏）
    m_thumbnailView = new ThumbnailView(this);
    m_thumbnailView->hide(); // 隐藏传统组件
    // 设置文件列表停靠窗口的可调整宽度（删除固定宽度限制）
    // m_fileBrowserDock->setFixedWidth(450); // 删除固定宽度，允许用户调整
    // 设置文件列表宽度为窗口宽度的2/5（40%）但不小于180px，确保文件名有足够显示空间
    int windowWidth = width();
    int fileBrowserWidth = qMax(windowWidth * 2 / 5, 180);  // 增加到40%宽度，最小180px

    // 设置最小宽度限制，但不设置最大宽度，允许用户自由调节
    m_fileBrowserDock->setMinimumWidth(100);  // 最小宽度100px，支持极致紧凑布局
    
    // 设置dock widget的尺寸策略，确保能够正确响应尺寸变化
    m_fileBrowserDock->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);

    // 连接dock widget的可见性变化信号，在第一次显示时设置正确宽度
    static bool firstShow = true;
    connect(m_fileBrowserDock, &QDockWidget::visibilityChanged, this, [this, firstShowPtr = &firstShow](bool visible) {
        if (visible && *firstShowPtr) {
            *firstShowPtr = false;
            // 使用保存的宽度，如果没有保存则使用最小宽度100
            int targetWidth = (m_savedFileBrowserWidth > 0) ? m_savedFileBrowserWidth : 100;

            // 使用resizeDocks方法在显示时设置宽度
            QList<QDockWidget*> docks = {m_fileBrowserDock};
            QList<int> sizes = {targetWidth};
            resizeDocks(docks, sizes, Qt::Horizontal);

            // 验证设置
            QTimer::singleShot(50, this, [this, targetWidth]() {
                int actualWidth = m_fileBrowserDock->width();
            });
        }
    });

    // 设置缩略图停靠窗口的固定宽度，与缩略图尺寸匹配
    m_thumbnailDock->setFixedWidth(220);
    // 添加布局调试日志
    // 连接文件列表信号
    connect(m_fileBrowser, &CustomFileBrowser::fileSelected,
            this, &MainWindow::onFileSelected);
    connect(m_fileBrowser, &CustomFileBrowser::fileRemoved,
            this, &MainWindow::onFileRemoved);
    connect(m_fileBrowser, &CustomFileBrowser::filesChanged,
            this, &MainWindow::onFilesChanged);
    connect(m_fileBrowser, &CustomFileBrowser::filesReordered,
            this, &MainWindow::onFilesReordered);
    connect(m_fileBrowser, &CustomFileBrowser::settingsChanged,
            this, &MainWindow::onSettingsChanged);
    connect(m_fileBrowser, &CustomFileBrowser::exportRequested,
            this, &MainWindow::onExportRequested);
    connect(m_fileBrowser, &CustomFileBrowser::previewRequested,
            this, &MainWindow::onPreviewRequested);
    connect(m_fileBrowser, &CustomFileBrowser::clearAllRequested,
            this, &MainWindow::onClearAllRequested);
    connect(m_fileBrowser, &CustomFileBrowser::resetProgramRequested,
            this, &MainWindow::onResetProgramRequested);
    connect(m_fileBrowser, &CustomFileBrowser::layoutModeRequested,
            this, &MainWindow::onLayoutModeRequested);
    // 连接文件浏览器信号到设置面板，实现实时页数更新
    connect(m_fileBrowser, &CustomFileBrowser::filesChanged,
            m_settingsWidget, &SettingsWidget::onFileListChanged);
    connect(m_fileBrowser, &CustomFileBrowser::fileRemoved,
            m_settingsWidget, &SettingsWidget::onFileListChanged);
    connect(m_fileBrowser, &CustomFileBrowser::settingsChanged,
            m_settingsWidget, &SettingsWidget::onPageCountChanged);
    // 连接总页数变化信号，实现布局感知的实时页数更新
    connect(m_fileBrowser, &CustomFileBrowser::totalDisplayPagesChanged,
            m_settingsWidget, &SettingsWidget::onPageCountChanged);
    // Martin Fowler重构：通过ApplicationStateManager统一管理总页数更新
    connect(m_fileBrowser, &CustomFileBrowser::totalDisplayPagesChanged,
            this, &MainWindow::onTotalDisplayPagesChanged);
    
    // 连接GlobalPageManager的页码偏移变化信号
    connect(&GlobalPageManager::instance(), &GlobalPageManager::pageNumberStartOffsetChanged,
            this, [this](int startOffset) {
                // 页码偏移变化时，强制更新PageView页码显示
                if (m_pageView) {
                    m_pageView->forceUpdatePageNumbers();
                }
                // 更新状态栏显示
                if (m_statusBarManager) {
                    int currentGlobalPage = m_pageView->getCurrentPageNumber();
                    int totalPages = GlobalPageManager::instance().getTotalGlobalPages();
                    m_statusBarManager->updateCurrentGlobalPage(currentGlobalPage, totalPages);
                }
            });
    // 文件处理元数据信号将在FileProcessWorker中直接连接
    // 连接统一状态管理器信号
    connect(LayoutStateManager::instance(), &LayoutStateManager::currentFileChanged,
            this, [this](const QString& fileIdentity) {
                // 可以在这里处理当前文件变更逻辑
            });
    // 连接布局模式变更信号，确保工具栏状态同步
    connect(LayoutStateManager::instance(), &LayoutStateManager::layoutModeChanged,
            this, [this](const QString& fileIdentity, LayoutMode mode) {
                // 检查是否是当前文件的布局模式变更
                QString currentFileIdentity = this->currentFileIdentity();
                if (currentFileIdentity == fileIdentity) {
                    // 更新内部状态
                    m_currentMode = mode;
                    // 如果当前有页面，重新排列页面
                    if (!m_pages.isEmpty()) {
                        auto layout = m_unifiedRenderer->rearrangePagesForColumns(m_pages, mode);
                        if (mode != LayoutMode::SingleColumn) {
                            // 对于多栏模式，需要生成布局矩形信息
                            QHash<int, QHash<int, QRect>> layoutRects;
                            // TODO: 实现布局矩形计算逻辑
                            m_pageView->setPages(layout, layoutRects);
                        } else {
                            m_pageView->setPages(layout);
                        }
                        m_pageView->setCurrentPage(0);
                        // Martin Fowler重构：移除重复的fitHeight调用，PageView会自动应用智能缩放
                    }
                }
            });
    // 连接批量布局模式变更信号，更新文件列表中所有受影响的文件
    connect(LayoutStateManager::instance(), &LayoutStateManager::batchLayoutModeChanged,
            this, [this](const QStringList& fileIdentities, LayoutMode mode) {
                // 更新CustomFileListWidget中受影响文件的显示
                for (const QString& fileIdentity : fileIdentities) {
                    // 找到对应的文件索引
                    int fileIndex = findFileIndexByIdentity(fileIdentity);
                    if (fileIndex >= 0) {
                        // 更新文件列表中的布局模式显示
                        int oldLayoutMode = LayoutStateManager::convertToOldLayoutMode(mode);
                        m_fileBrowser->updateFileLayoutMode(fileIndex, oldLayoutMode);
                    }
                }
            });
    // 统一缓存管理器不需要信号连接
    // 创建图像处理器
    m_imageProcessor = new ImageProcessor(this);
    // Martin Fowler重构：Dependency Injection - 注入DPI配置
    updateImageProcessorDpiConfig();
    // 连接信号和槽（使用自定义映射）
    connect(m_thumbnailView, &ThumbnailView::pageSelected,
            this, &MainWindow::onThumbnailPageSelected);
    connect(m_pageView, &PageView::pageChanged,
            this, &MainWindow::onMainPageChanged);
    connect(m_pageView, &PageView::pageChanged,
            m_settingsWidget, &SettingsWidget::onCurrentPageChanged);
    connect(m_pageView, &PageView::thumbnailClicked,
            this, &MainWindow::onPageViewThumbnailClicked);
    connect(m_pageView, &PageView::needMorePages,
            this, &MainWindow::onNeedMorePages);
    connect(m_pageView, &PageView::logMessage,
            this, [](const QString& message) {
            });
    m_mainToolBar = nullptr;  // 初始化为nullptr
    // TDD: 初始化统一内存管理系统
    setupUnifiedMemoryManagement();
}
void MainWindow::clearLogsOnStartup()
{
    const QString baseDir = QDir::currentPath();
    const QStringList logFiles = { "debug.log", "pdf_debug.log", "fileprocessworker_debug.log" };
    for (const QString& name : logFiles) {
        QString path = baseDir + QDir::separator() + name;
        QFile f(path);
        if (f.exists()) {
            f.remove();
        }
    }
}
bool MainWindow::loadSettings()
{
    
    // 使用SystemConfigManager加载窗口状态
    SystemConfigManager& configMgr = SystemConfigManager::instance();
    
    // 加载窗口几何信息
    QByteArray geometry = configMgr.getWindowGeometry();
    if (!geometry.isEmpty()) {
        restoreGeometry(geometry);
    } else {
    }
    
    // 加载停靠窗口状态
    QByteArray dockState = configMgr.getDockWidgetState();
    if (!dockState.isEmpty()) {
        restoreState(dockState);
    } else {
    }
    
    // 加载停靠窗口可见性
    bool fileBrowserVisible = configMgr.getFileBrowserVisible();
    bool thumbnailVisible = configMgr.getThumbnailVisible();
    
    if (m_fileBrowserDock) {
        if (fileBrowserVisible) {
            m_fileBrowserDock->show();
            m_toggleLeftSidebarAction->setChecked(true);
        } else {
            m_fileBrowserDock->hide();
            m_toggleLeftSidebarAction->setChecked(false);
        }
    }
    
    if (m_thumbnailDock) {
        if (thumbnailVisible) {
            m_thumbnailDock->show();
            m_toggleRightSidebarAction->setChecked(true);
        } else {
            m_thumbnailDock->hide();
            m_toggleRightSidebarAction->setChecked(false);
        }
    }
    
    // 加载停靠窗口宽度到成员变量，在显示时应用
    m_savedFileBrowserWidth = configMgr.getFileBrowserWidth();
    m_savedThumbnailWidth = configMgr.getThumbnailWidth();
    
    return true;
}
void MainWindow::saveSettings()
{
    
    // 使用SystemConfigManager保存窗口状态
    SystemConfigManager& configMgr = SystemConfigManager::instance();
    
    // 保存窗口几何信息
    QByteArray geometry = saveGeometry();
    if (!geometry.isEmpty()) {
        configMgr.setWindowGeometry(geometry);
    } else {
    }
    
    // 保存停靠窗口状态
    QByteArray dockState = saveState();
    if (!dockState.isEmpty()) {
        configMgr.setDockWidgetState(dockState);
    } else {
    }
    
    // 保存停靠窗口可见性
    bool fileBrowserVisible = m_fileBrowserDock ? m_fileBrowserDock->isVisible() : false;
    bool thumbnailVisible = m_thumbnailDock ? m_thumbnailDock->isVisible() : false;
    
    configMgr.setFileBrowserVisible(fileBrowserVisible);
    configMgr.setThumbnailVisible(thumbnailVisible);
    
    // 保存停靠窗口宽度
    int fileBrowserWidth = m_fileBrowserDock ? m_fileBrowserDock->width() : 0;
    int thumbnailWidth = m_thumbnailDock ? m_thumbnailDock->width() : 0;
    
    configMgr.setFileBrowserWidth(fileBrowserWidth);
    configMgr.setThumbnailWidth(thumbnailWidth);
    
    // 确保配置保存到磁盘
    configMgr.saveConfig();
    
}

void MainWindow::applyDockWidgetWidths()
{
    // 此方法已废弃，宽度在dock widget显示时应用
}

void MainWindow::resizeEvent(QResizeEvent* event)
{
    QMainWindow::resizeEvent(event);
    
    // 延迟保存窗口状态，避免频繁保存
    if (m_initializationComplete) {
        QTimer::singleShot(1000, this, [this]() {
            saveSettings();
        });
    }
}

void MainWindow::moveEvent(QMoveEvent* event)
{
    QMainWindow::moveEvent(event);
    
    // 延迟保存窗口状态，避免频繁保存
    if (m_initializationComplete) {
        QTimer::singleShot(1000, this, [this]() {
            saveSettings();
        });
    }
}
void MainWindow::createActions()
{
    // 列显示动作
    singleColumnAct = new QAction(IconFactory::createIcon(IconFactory::SingleColumn), tr("单栏显示"), this);
    twoColumnsAct = new QAction(IconFactory::createIcon(IconFactory::TwoColumns), tr("双栏显示"), this);
    threeColumnsAct = new QAction(IconFactory::createIcon(IconFactory::ThreeColumns), tr("三栏显示"), this);
    m_zoomInAction = new QAction(IconFactory::createIcon(IconFactory::ZoomIn), tr("放大"), this);
    m_zoomOutAction = new QAction(IconFactory::createIcon(IconFactory::ZoomOut), tr("缩小"), this);
    m_fitHeightAction = new QAction(IconFactory::createIcon(IconFactory::FitHeight), tr("适合高度"), this);
    m_fitWidthAction = new QAction(IconFactory::createIcon(IconFactory::FitWidth), tr("适合宽度"), this);
    
// 新增的导入导出Action
    m_loadAction = new QAction(IconFactory::createIcon(IconFactory::Import), tr("导入文件..."), this);
    m_exportAction = new QAction(IconFactory::createIcon(IconFactory::Export), tr("导出为PDF..."), this);
    m_systemConfigAction = new QAction(IconFactory::createIcon(IconFactory::Settings), tr("系统设置"), this);
    m_systemLoginAction = new QAction(IconFactory::createIcon(IconFactory::SystemLogin), tr("登录"), this);
    
    // 退出动作
    m_exitAction = new QAction(tr("退出"), this);
    connect(m_exitAction, &QAction::triggered, this, &QWidget::close);
    
    // 关于动作
    m_aboutAction = new QAction(tr("关于"), this);
    connect(m_aboutAction, &QAction::triggered, this, [this]() {
        showAboutDialog();
    });

    connect(singleColumnAct, &QAction::triggered, this, &MainWindow::safeSingleColumn);
    connect(twoColumnsAct, &QAction::triggered, this, &MainWindow::safeTwoColumns);
    connect(threeColumnsAct, &QAction::triggered, this, &MainWindow::safeThreeColumns);
    connect(m_zoomInAction, &QAction::triggered, this, &MainWindow::safeZoomIn);
    connect(m_zoomOutAction, &QAction::triggered, this, &MainWindow::safeZoomOut);
    connect(m_exportAction, &QAction::triggered, this, &MainWindow::exportToPdf);
    connect(m_systemConfigAction, &QAction::triggered, this, &MainWindow::showSystemConfigDialog);
    connect(m_systemLoginAction, &QAction::triggered, this, &MainWindow::showSystemLoginDialog);
    connect(m_loadAction, &QAction::triggered, this, &MainWindow::openImage);
    connect(m_fitWidthAction, &QAction::triggered, this, &MainWindow::safeFitWidth);
    connect(m_fitHeightAction, &QAction::triggered, this, &MainWindow::safeFitHeight);


    // 创建批处理动作
    // 创建侧边栏切换动作
    // 创建使用在线版动作
    m_checkUpdateAction = new QAction(tr("使用在线版"), this);
    connect(m_checkUpdateAction, &QAction::triggered,
            this, [this]() { openOnlineVersion(); });
    // 关于动作已在上面初始化
    // 创建语言相关的动作
    m_englishAction = new QAction("English", this);
    m_englishAction->setCheckable(true);
    m_englishAction->setData("en");
    connect(m_englishAction, &QAction::triggered, 
            this, [this]() { switchLanguage("en"); });
    m_chineseSimplifiedAction = new QAction("简体中文", this);
    m_chineseSimplifiedAction->setCheckable(true);
    m_chineseSimplifiedAction->setData("zh_CN");
    connect(m_chineseSimplifiedAction, &QAction::triggered, 
            this, [this]() { switchLanguage("zh_CN"); });
        // 创建侧边栏切换动作
    m_toggleLeftSidebarAction = new QAction(QIcon(":/icons/filebrowser.png"), tr("文件列表"), this);
    m_toggleLeftSidebarAction->setCheckable(true);
    connect(m_toggleLeftSidebarAction, &QAction::triggered, this, &MainWindow::toggleLeftSidebar);
    m_toggleRightSidebarAction = new QAction(QIcon(":/icons/thumbnail.png"), tr("缩略图"), this);
    m_toggleRightSidebarAction->setCheckable(true);
    connect(m_toggleRightSidebarAction, &QAction::triggered, this, &MainWindow::toggleRightSidebar);

    // 初始化状态栏管理器和导出管理器
    initializeStatusBar();
    // 连接空间监控信号
    connect(m_cacheManager, &UnifiedCacheManager::diskSpaceLow,
            this, [this](double availableGB, int thresholdGB) {
        QString message = QString("磁盘空间不足警告：仅%.1f GB可用，低于%1 GB阈值").arg(availableGB).arg(thresholdGB);
        QMessageBox::warning(this, "磁盘空间警告", message);
    });
    connect(m_cacheManager, &UnifiedCacheManager::diskSpaceWarning,
            this, [this](const QString& message) {
        statusBar()->showMessage(message, 10000); // 显示10秒
    });
}
void MainWindow::createToolBar()
{
    // 如果工具栏不存在，创建新的工具栏
    if (!m_mainToolBar) {
        m_mainToolBar = new QToolBar(tr("工具栏"), this);
        m_mainToolBar->setObjectName("mainToolBar");  // 设置objectName
        addToolBar(m_mainToolBar);
    } else {
        // 如果工具栏已存在，清除所有动作
        m_mainToolBar->clear();
    }
    m_mainToolBar->addAction(m_systemLoginAction);
    m_mainToolBar->addSeparator();
    // 添加列显示模式按钮
    m_mainToolBar->addAction(singleColumnAct);
    m_mainToolBar->addAction(twoColumnsAct);
    m_mainToolBar->addAction(threeColumnsAct);
    m_mainToolBar->addSeparator();
    // 添加缩放控制按钮
    m_mainToolBar->addAction(m_fitWidthAction);
    m_mainToolBar->addAction(m_fitHeightAction);
    m_mainToolBar->addAction(m_zoomInAction);
    m_mainToolBar->addAction(m_zoomOutAction);
    m_mainToolBar->addSeparator();
    m_mainToolBar->addAction(m_systemConfigAction);
}
void MainWindow::initializeStatusBar()
{
    // 创建流式导出管理器（内部自动创建独立渲染器和连接缓存）
    m_streamingExportManager = new StreamingExportManager(this);
    // 注意：渲染器在内部创建（线程安全），缓存使用单例（公用）
    
    // 创建应用状态管理器 - 解决Shotgun Surgery问题
    m_appStateManager = new ApplicationStateManager(this);
    
    // 创建状态栏管理器
    m_statusBarManager = new StatusBarManager(this, statusBar(), this);

    // 连接导出管理器到状态栏管理器
    m_statusBarManager->setStreamingExportManager(m_streamingExportManager);

    // Martin Fowler重构：重新连接导出可用性信号到StatusBarManager
    connect(m_fileBrowser, &CustomFileBrowser::exportAvailabilityChanged,
            m_statusBarManager, &StatusBarManager::setExportAvailable);
    
    // === 关键修复：信号连接后主动设置初始导出按钮状态为禁用 ===
    // 初始化时文件列表为空或文件未处理完成，按钮应该是禁用状态
    // 后续状态由 exportAvailabilityChanged 信号动态更新
    if (m_statusBarManager) {
        m_statusBarManager->setExportAvailable(false);
    }
    
    // 注册组件到状态管理器
    m_appStateManager->setStatusBarManager(m_statusBarManager);
    // 连接状态栏信号到主窗口的处理方法
    connect(m_statusBarManager, &StatusBarManager::oneClickExportRequested,
            this, &MainWindow::onOneClickExport);

    // 连接更新按钮信号
    connect(m_statusBarManager, &StatusBarManager::updateRequested,
            this, &MainWindow::onUpdateRequested);

    // 连接面板切换信号
    connect(m_statusBarManager, &StatusBarManager::toggleFileListRequested,
            this, &MainWindow::toggleLeftSidebar);
    connect(m_statusBarManager, &StatusBarManager::togglePreviewRequested,
            this, &MainWindow::toggleRightSidebar);
    
    // 连接导出完成toast信号
    connect(m_statusBarManager, &StatusBarManager::exportCompletedToast,
            this, &MainWindow::showToastMessage);
    
    // 连接导出失败toast信号
    connect(m_statusBarManager, &StatusBarManager::exportFailedToast,
            this, &MainWindow::showToastMessage);
    
    // 取消导出不需要Toast提示（用户主动操作）
    // Martin Fowler重构：减少对用户的干扰
    
    // 连接文件夹打开toast信号
    connect(m_statusBarManager, &StatusBarManager::folderOpenToast,
            this, &MainWindow::showToastMessage);
    
    // 已移除配置和缓存按钮的信号连接
    // connect(m_statusBarManager, &StatusBarManager::exportSettingsRequested,
    //         this, &MainWindow::onExportSettings);
    // connect(m_statusBarManager, &StatusBarManager::cacheManagementRequested,
    //         this, &MainWindow::onCacheManagement);
    // 连接文件列表信号更新状态栏
    if (m_fileBrowser) {
        connect(m_fileBrowser, &CustomFileBrowser::fileSelected,
                this, [this](int index, const UnifiedFileInfo& file) {
                    updateStatusBarFileInfo();
                });
    }
    // 连接页面视图信号更新状态栏
    if (m_pageView) {
        connect(m_pageView, &PageView::pageChanged,
                this, [this](int page) {
                    // 页码变化处理 - 更新状态栏全局页码显示
                    if (m_statusBarManager) {
                        int currentGlobalPage = m_pageView->getCurrentPageNumber();
                        // 使用全局总页数而不是当前文件的页数
                        int totalPages = GlobalPageManager::instance().getTotalGlobalPages();
                        m_statusBarManager->updateCurrentGlobalPage(currentGlobalPage, totalPages);
                    }
                });
    }
}
void MainWindow::createMenus()
{
    // 在macOS上，隐藏应用程序内部的菜单栏，使用系统菜单栏
    #ifdef Q_OS_MACOS
    menuBar()->setVisible(false);
    #endif

    QMenu *fileMenu = menuBar()->addMenu(tr("文件"));
    fileMenu->setObjectName("fileMenu");
    fileMenu->addAction(m_loadAction);
    fileMenu->addSeparator();
    fileMenu->addAction(m_systemConfigAction);
    fileMenu->addSeparator();
    fileMenu->addAction(m_exitAction);
    QMenu *viewMenu = menuBar()->addMenu(tr("视图"));
    viewMenu->setObjectName("viewMenu");
    viewMenu->addAction(singleColumnAct);
    viewMenu->addAction(twoColumnsAct);
    viewMenu->addAction(threeColumnsAct);
    viewMenu->addSeparator();
    viewMenu->addAction(m_fitWidthAction);
    viewMenu->addAction(m_fitHeightAction);
    viewMenu->addAction(m_zoomInAction);
    viewMenu->addAction(m_zoomOutAction);
    
    // 编辑菜单已删除 - 系统设置功能在文件菜单中已存在，避免重复
    
    QMenu *helpMenu = menuBar()->addMenu(tr("帮助"));
    helpMenu->setObjectName("helpMenu");
    helpMenu->addAction(m_checkUpdateAction);
    helpMenu->addSeparator();
    helpMenu->addAction(m_aboutAction);
    
}
void MainWindow::processImage()
{
    if (m_originalImage.isNull()) {
        return;
    }
    // 重置列模式为单栏
    m_currentMode = LayoutMode::SingleColumn;
    // 只在单文件处理时显示进度对话框
    ProgressDialog* progress = nullptr;
    bool showProgress = true; // 可以通过参数控制
    if (showProgress) {
        progress = new ProgressDialog(this);
        progress->setWindowTitle(tr("处理图片"));
        progress->setDetailedProgress(tr("正在分析图片..."), 0, 100, "");
        progress->show();
    }
    if (progress) progress->setDetailedProgress(tr("正在分析图片..."), 10, 100, "");
    qApp->processEvents();
    if (progress) progress->setDetailedProgress(tr("正在检测背景颜色..."), 20, 100, "");
    qApp->processEvents();
    if (progress) progress->setDetailedProgress(tr("正在计算分割位置..."), 30, 100, "");
    qApp->processEvents();
    if (progress) progress->setDetailedProgress(tr("正在分割图片..."), 50, 100, "");
    qApp->processEvents();
    // 使用统一系统处理图片分页
    // 清理之前的内存缓存（类似PDF处理）
    m_loadedPages.clear();
    m_loadedPageIndices.clear();
    // 预计算图片分割位置（确保一致性）
    precalculateImageSplitPositions(m_originalImage);
    // 计算总页数
    int totalPages = calculateImagePageCount(m_originalImage, m_currentMode);
    // 这个函数现在应该被删除，因为所有处理都应该通过FileProcessWorker完成
}
void MainWindow::updatePageView(int index)
{
    if (index >= 0 && index < m_pages.size()) {
        m_pageView->setCurrentPage(index);
    }
}
void MainWindow::openImage()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(this,
        tr("导入文件"),
        QDir::homePath(),
        tr("图片文件 (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.webp);;PDF文件 (*.pdf);;所有文件 (*.*)"));
    
    if (fileNames.isEmpty())
        return;
    
    
    // 使用统一的文件处理流程：添加到文件列表并启动处理任务
    m_fileBrowser->addFiles(fileNames);
    
    // 显示文件列表（宽度由visibilityChanged信号自动处理）
    m_fileBrowserDock->show();
    m_toggleLeftSidebarAction->setChecked(true);
    
    // 显示预览面板，设置宽度为220px
    m_thumbnailDock->show();
    m_toggleRightSidebarAction->setChecked(true);
    m_thumbnailDock->resize(220, m_thumbnailDock->height());
    
    // 启动文件处理任务
    startFileProcessing();
}
void MainWindow::switchColumnMode(LayoutMode newMode, bool fromFileBrowser)
{
    // 检查是否已经是目标模式，避免重复处理
    if (m_currentMode == newMode) {
        return;
    }
    // 更新当前模式
    m_currentMode = newMode;
    // 通过统一状态管理器同步布局设置（仅当不是来自文件列表的请求时）
    if (!fromFileBrowser) {
        QString currentFileIdentity = this->currentFileIdentity();
        if (!currentFileIdentity.isEmpty()) {
            // 直接使用统一的布局模式枚举
            LayoutMode mode = static_cast<LayoutMode>(newMode);
            LayoutStateManager::instance()->setFileLayoutMode(currentFileIdentity, mode);
            // 触发文件列表的显示刷新，让自定义控件更新布局状态显示
            LayoutStateManager::instance()->displayRefreshNeeded();
        } else {
        }
    } else {
    }
    // 检查是否有当前文档
    if (m_pages.isEmpty()) {
        // 显示占位符
        QList<QImage> placeholders = createLayoutPlaceholders(newMode);
        m_pageView->setPages(placeholders);
        m_pageView->setCurrentPage(0);
        return;
    }
    // 统计原始页面中已加载的页面数量
    int loadedPages = 0;
    for (int i = 0; i < m_pages.size(); ++i) {
        const QImage& img = m_pages[i];
        if (NextGenPlaceholder::isRealContent(img)) {
            loadedPages++;
        }
    }
    // 如果页面数量不足，显示占位符
    if (loadedPages == 0) {
        QList<QImage> placeholders = createLayoutPlaceholders(newMode);
        m_pageView->setPages(placeholders);
        m_pageView->setCurrentPage(0);
        return;
    }
    // 重新排列页面（打包返回页面+布局）
    auto layoutNew = m_unifiedRenderer->rearrangeWithLayout(m_pages, newMode);
    // 只更新大图显示，缩略图保持不变
    if (newMode != LayoutMode::SingleColumn) {
        m_pageView->setPages(layoutNew.pages, layoutNew.layoutRects);
    } else {
        m_pageView->setPages(layoutNew.pages);
    }
    m_pageView->setCurrentPage(0);
}
QString MainWindow::currentFileIdentity() const
{
    if (!m_currentFileHash.isEmpty()) return m_currentFileHash;
    if (m_fileBrowser) return m_fileBrowser->getCurrentFileIdentity();
    return QString();
}
int MainWindow::findFileIndexByIdentity(const QString& fileIdentity) const
{
    if (m_fileBrowser) {
        // 通过CustomFileBrowser查找文件索引
        QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
        for (int i = 0; i < files.size(); i++) {
            QString currentIdentity = FileIdentityManager::getFileIdentity(files[i].filePath);
            if (currentIdentity == fileIdentity) {
                return i;
            }
        }
    }
    return -1; // 未找到
}
void MainWindow::applyLayoutModeToSelectedFiles(LayoutMode mode)
{
    if (!m_fileBrowser) {
        return;
    }
    // 检查是否有选中的文件
    QList<int> selectedIndices = m_fileBrowser->getSelectedIndices();
    if (selectedIndices.isEmpty()) {
        // 没有选中的文件，应用到当前文件
        switchColumnMode(mode);
    } else {
        // 有选中的文件，使用现有的批量布局功能
        // Martin Fowler重构：布局模式功能已委托给CustomFileListWidget的FileListContextMenu
        // 这里直接应用布局模式到选中的文件
        for (int index : selectedIndices) {
            m_fileBrowser->setFileLayoutMode(index, mode);
        }
    }
}
int MainWindow::dpiBucketForHeight(int pixelHeight) const
{
    // 简单分桶：720,1080,1440,2160
    if (!m_dpiBuckets.isEmpty()) {
        for (int b : m_dpiBuckets) {
            if (pixelHeight <= b) return b;
        }
        return m_dpiBuckets.last();
    }
    if (pixelHeight <= 800) return 720;
    if (pixelHeight <= 1200) return 1080;
    if (pixelHeight <= 1700) return 1440;
    return 2160;
}
// 计算A4目标预览高度（像素），考虑有效DPI、窗口缩放与DPR，并通过桶量化（带回滞）
int MainWindow::targetA4PreviewHeightPx(double scale) const
{
    // A4高度英寸 ≈ 11.69
    double effectiveDpi = getEffectiveDpi();
    double deviceRatio = this->devicePixelRatioF();
    int desired = static_cast<int>(11.69 * effectiveDpi * deviceRatio * qMax(0.1, scale));
    // 选择桶（不允许上采样的量化逻辑在selectBucketHeightWithHysteresis里处理）
    return selectBucketHeightWithHysteresis(desired);
}
int MainWindow::selectBucketHeightWithHysteresis(int desiredHeight) const
{
    if (m_dpiBuckets.isEmpty()) {
        return desiredHeight; // 无桶时直接使用
    }
    // 禁止上采样：期望高度不能超过缓存原图高度。此处采用最大桶且不超过期望高度
    int chosen = m_dpiBuckets.first();
    for (int b : m_dpiBuckets) {
        if (b <= desiredHeight) chosen = b; else break;
    }
    // 回滞：若与上一次桶接近（±10%内），维持上一次，避免抖动
    int last = m_lastBucketHeight;
    if (last > 0) {
        double low = last * (1.0 - BUCKET_HYSTERESIS_RATIO);
        double high = last * (1.0 + BUCKET_HYSTERESIS_RATIO);
        if (chosen >= static_cast<int>(low) && chosen <= static_cast<int>(high)) {
            return last;
        }
    }
    // 更新记忆并返回
    m_lastBucketHeight = chosen;
    return chosen;
}
void MainWindow::loadCacheSettings()
{
    
    // 读取 DPI 桶配置（按A4高度像素：1123(96DPI),1404(120),1754(150),2339(200),3508(300),7016(600)）
    QString buckets = ConfigManager::getDpiBuckets();
    m_dpiBuckets.clear();
    for (const QString& s : buckets.split(',', Qt::SkipEmptyParts)) {
        bool ok = false; int v = s.trimmed().toInt(&ok);
        if (ok) m_dpiBuckets.append(v);
    }
    std::sort(m_dpiBuckets.begin(), m_dpiBuckets.end());
}
int MainWindow::mapThumbnailToMainPage(int thumbnailIndex)
{
    // **修复**: 正确的映射逻辑
    // 缩略图索引 = 原始页面索引，需要计算该原始页面属于哪个组合页面
    if (m_currentMode == LayoutMode::SingleColumn) {
        // 单栏模式：1对1映射，缩略图直接对应原始页面
        return thumbnailIndex;
    } else {
        // 多栏模式：计算原始页面属于哪个组合页面
        int pagesPerComposite = m_unifiedRenderer->pagesPerComposite(m_currentMode);
        int compositePageIndex = thumbnailIndex / pagesPerComposite;
        return compositePageIndex;
    }
}
int MainWindow::mapMainPageToThumbnail(int mainPageIndex)
{
    // 将主视图页面索引映射到缩略图索引
    // 返回该主页面包含的第一个原始页面的索引
    if (m_currentMode == LayoutMode::SingleColumn) {
        // 单栏模式：1对1映射
        return mainPageIndex;
    } else if (m_currentMode == LayoutMode::TwoColumns) {
        // 二栏式：1个重排页面包含4个原始页面
        return mainPageIndex * 4;
    } else if (m_currentMode == LayoutMode::ThreeColumns) {
        // 三栏式：1个重排页面包含9个原始页面
        return mainPageIndex * 9;
    }
    return mainPageIndex;
}
void MainWindow::onThumbnailPageSelected(int thumbnailIndex)
{
    navigateAndHighlight(thumbnailIndex, NavigationIntent::FromTraditionalThumbnail);
}
void MainWindow::onMainPageChanged(int mainPageIndex)
{
    // 主视图页面变化，只做滚动同步，不做选中同步
    int thumbnailIndex = mapMainPageToThumbnail(mainPageIndex);
    // 管理m_pages内存限制
    managePagesMemory(mainPageIndex);
    // 智能预加载附近页面
    preloadNearbyPages(mainPageIndex);
    // 设置不需要居中显示（这是滚动浏览）
    if (m_pageView) {
        m_pageView->setShouldCenterOnUpdate(false);
    }
    // 清除所有选中状态
    if (m_thumbnailView) {
        // 暂时断开信号连接，避免触发选中同步
        disconnect(m_thumbnailView, &ThumbnailView::pageSelected,
                  this, &MainWindow::onThumbnailPageSelected);
        // 清除选中状态，但保持可见性
        m_thumbnailView->setCurrentRow(-1);
        // 重新连接信号
        connect(m_thumbnailView, &ThumbnailView::pageSelected,
                this, &MainWindow::onThumbnailPageSelected);
    }
    // 清除主视图的高亮（保护一次：防止刚跳转就被清空）
    if (m_pageView) {
        if (m_skipClearHighlightOnce) {
            m_skipClearHighlightOnce = false;
        } else {
            m_pageView->clearHighlight();
        }
    }
    // 确保缩略图滚动到对应位置，但不设置选中
    if (m_thumbnailView && thumbnailIndex >= 0 && thumbnailIndex < m_thumbnailView->count()) {
        // 滚动到对应位置，但不选中
        QListWidgetItem* item = m_thumbnailView->item(thumbnailIndex);
        if (item) {
            m_thumbnailView->scrollToItem(item, QAbstractItemView::PositionAtCenter);
        }
    }
}
void MainWindow::onPageViewThumbnailClicked(int thumbnailIndex)
{
    if (thumbnailIndex < 0) {
        if (m_thumbnailView) m_thumbnailView->setCurrentRow(-1);
        if (m_pageView) m_pageView->clearHighlight();
        return;
    }
    navigateAndHighlight(thumbnailIndex, NavigationIntent::FromMainView);
}
void MainWindow::onNeedMorePages(int startIndex, int count)
{
    // **新增**: 可见区域优先级处理
    int currentPage = m_pageView ? m_pageView->currentPage() : 0;
    bool isVisibleArea = (startIndex <= currentPage + 2 && startIndex + count >= currentPage - 2);
    if (isVisibleArea) {
    }
    // 从状态获取当前文件的hash（避免UI未及时更新导致为空）
    QString currentFileIdentity = this->currentFileIdentity();
    if (currentFileIdentity.isEmpty()) {
        return;
    }
    // **关键修复**: 动态检查实际页面数并扩展
    QString cacheKey = FileIdentityManager::getCacheKey(currentFileIdentity);
    QString cacheDir = m_cacheManager->getCacheDirectory() + "/" + cacheKey;
    QDir dir(cacheDir);
    int actualPages = m_pdfPageCount; // 默认使用当前记录的页数
    if (dir.exists()) {
        QStringList pageFiles = dir.entryList(QStringList() << "page_*.png", QDir::Files);
        actualPages = pageFiles.size();
        // **智能扩展策略**: 只在用户真正需要新页面时才刷新
        if (actualPages > m_pdfPageCount) {
            int pageIncrease = actualPages - m_pdfPageCount;
            // 更新记录的页数
            m_pdfPageCount = actualPages;
            // 扩展m_pages数组
            while (m_pages.size() < actualPages) {
                QImage placeholder = NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中...");
                m_pages.append(placeholder);
            }
            // **智能刷新判断**: 检查用户是否滚动到了需要新页面的位置
            bool shouldRefreshView = false;
            if (m_pageView) {
                int currentPage = m_pageView->currentPage();
                int totalLoadedPages = m_pages.size();
                // 只有用户滚动到已加载页面的最后几页时，才需要刷新视图
                bool isNearEnd = (currentPage >= totalLoadedPages - 3); // 距离末尾3页内
                bool isRequestingNewPages = (startIndex >= totalLoadedPages - 5); // 请求的是接近末尾的页面
                shouldRefreshView = isNearEnd || isRequestingNewPages;
            }
            if (shouldRefreshView) {
                // 用户滚动到了需要新页面的位置，立即刷新视图
                if (m_pageView && m_currentMode == LayoutMode::SingleColumn) {
                    m_pageView->setPagesPreservingScroll(m_pages);
                }
            } else {
                // 用户没有滚动到需要新页面的位置，只扩展页数
            }
            // 总是扩展总页数
            if (m_pageView) {
                m_pageView->expandTotalPageCount(actualPages);
            }
        }
    }
    int totalPages = actualPages;
    // 在多列模式下，startIndex 是组合页的索引，需要转换为原始页面的索引范围
    if (m_currentMode != LayoutMode::SingleColumn) {
        // 计算该组合页包含的原始页面范围
        int pagesPerComposite = (m_currentMode == LayoutMode::TwoColumns) ? 4 : 9;
        int startOriginalPage = startIndex * pagesPerComposite;
        int endOriginalPage = qMin(startOriginalPage + pagesPerComposite * count, totalPages);
        // 加载该组合页包含的所有原始页面
        for (int originalPageIndex = startOriginalPage; originalPageIndex < endOriginalPage; ++originalPageIndex) {
            // 直接加载缓存文件
            QString cacheKey = FileIdentityManager::getCacheKey(currentFileIdentity);
            QString cacheDir = m_cacheManager->getCacheDirectory() + "/" + cacheKey;
            QString fileName = QString("page_%1.png").arg(originalPageIndex, 5, 10, QChar('0'));
            QString filePath = cacheDir + "/" + fileName;
            QImage cachedPage;
            if (QFile::exists(filePath)) {
                cachedPage = QImage(filePath);
            }
            if (!cachedPage.isNull()) {
                // 更新 m_pages 列表中的页面数据
                if (originalPageIndex < m_pages.size()) {
                    m_pages[originalPageIndex] = cachedPage;
                } else {
                }
            } else {
            }
        }
        // 参考单栏式模式：只更新需要的组合页，不调用setPages
        QString fileIdentity = this->currentFileIdentity();
        int dpiBucket = dpiBucketForHeight(1754); // A4高度对应的DPI桶
        // 计算需要更新的组合页范围
        int compositePagesPerComposite = (m_currentMode == LayoutMode::TwoColumns) ? 4 : 9;
        int startCompositeIndex = startIndex;
        int endCompositeIndex = qMin(startIndex + count, (totalPages + compositePagesPerComposite - 1) / compositePagesPerComposite);
        // 检查m_pageView是否已经初始化
        if (m_pageView->pageCount() == 0) {
            return;
        }
        for (int compositeIndex = startCompositeIndex; compositeIndex < endCompositeIndex; ++compositeIndex) {
            // 重新生成组合页
            QImage compositePage = m_unifiedRenderer->composeCompositePageAt(m_pages, compositeIndex, m_currentMode);
            if (!compositePage.isNull()) {
                // 直接更新页面内容（不调用setPages）
                if (compositeIndex < m_pageView->pageCount()) {
                    m_pageView->updatePageContent(compositeIndex, compositePage);
                }
            }
        }
    } else {
        // 单栏模式：直接加载原始页面
        // **优化**: 可见区域优先级排序
        QList<int> pageIndices;
        for (int i = 0; i < count && (startIndex + i) < totalPages; ++i) {
            pageIndices.append(startIndex + i);
        }
        // **可见区域优先**: 按与当前页面的距离排序
        if (isVisibleArea) {
            std::sort(pageIndices.begin(), pageIndices.end(), [currentPage](int a, int b) {
                return qAbs(a - currentPage) < qAbs(b - currentPage);
            });
        }
        for (int pageIndex : pageIndices) {
            // **关键优化**: 可见区域使用同步加载，其他区域异步加载
            bool isCurrentVisible = (qAbs(pageIndex - currentPage) <= 1);
            QImage unifiedPage = loadPageFromUnifiedCache(pageIndex);
            if (!unifiedPage.isNull()) {
                // 更新 m_pages 列表中的页面数据
                if (pageIndex < m_pages.size()) {
                    m_pages[pageIndex] = unifiedPage;
                }
                // **可见区域立即更新**: 当前可见页面立即更新视图
                if (isCurrentVisible) {
                    m_pageView->updatePageContent(pageIndex, unifiedPage);
                    // 可见页面还需要刷新组合页面
                    if (m_currentMode != LayoutMode::SingleColumn) {
                        auto layout = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                        m_pageView->updatePagesWithoutReset(layout.pages);
                        m_pageView->setAccurateLayoutRects(layout.layoutRects);
                    }
                } else {
                    // 非可见页面延迟更新
                    QTimer::singleShot(LAYOUT_RECOMPUTE_DELAY_MS, this, [this, pageIndex, unifiedPage]() {
                        if (m_pageView) {
                            m_pageView->updatePageContent(pageIndex, unifiedPage);
                        }
                    });
                }
            } else {
                // 统一缓存服务也没有，缓存重建是预期行为，无需提示
            }
        }
    }
}
void MainWindow::onNeedMoreThumbnails(int startIndex, int count)
{
    QString currentFileIdentity = this->currentFileIdentity();
    if (currentFileIdentity.isEmpty()) {
        return;
    }
    // 检查是否有新生成的缩略图可以加载
    if (m_virtualThumbnailView) {
        // 触发检查并加载新的缩略图
        QTimer::singleShot(100, this, [this, currentFileIdentity]() {
            if (m_virtualThumbnailView) {
                m_virtualThumbnailView->refreshThumbnailsFromCache(currentFileIdentity);
            }
        });
    }
    // 如果文件仍在处理中，这个请求会促使渐进式加载检查该区域
    // 主要作用是让缩略图视图知道用户关心这个区域，优先加载这部分
}
void MainWindow::processFileToCache(const QString& filePath, ProgressDialog* progress)
{
    try {
        // 检查文件是否存在
        if (!QFile::exists(filePath)) {
            if (progress) {
                progress->setDetailedProgress(tr("文件不存在"), 0, 100, QFileInfo(filePath).fileName());
            }
            return;
        }
        // Martin Fowler重构：使用FileProcessWorker统一处理所有文件类型，注入DPI配置
    DpiConfiguration dpiConfig = getCurrentDpiConfiguration();
    FileProcessWorker* worker = new FileProcessWorker(0, filePath, dpiConfig, this);
    connect(worker, &FileProcessWorker::progressUpdated, this, [progress](int fileIndex, const UnifiedFileInfo& info) {
        if (progress) {
            progress->setProgress(info.progress, 100);
        }
    });
    connect(worker, &FileProcessWorker::processingFinished, this, [this, filePath](int fileIndex, bool success) {
        if (success) {
            // 处理完成后，从缓存加载文件
            loadFileFromCache(filePath);
        }
    });
        // 启动处理
        QThreadPool::globalInstance()->start(worker);
    } catch (const std::exception& e) {
        if (progress) {
            progress->setDetailedProgress(tr("处理异常: %1").arg(e.what()), 0, 100, QFileInfo(filePath).fileName());
        }
    } catch (...) {
        if (progress) {
            progress->setDetailedProgress(tr("处理出现未知异常"), 0, 100, QFileInfo(filePath).fileName());
        }
    }
}
// 已删除：processPDFToCache - 现在使用FileProcessWorker统一处理
// 已删除：processImageToCache - 现在使用FileProcessWorker统一处理
int MainWindow::estimatePDFPages(const QString& filePath)
{
#ifdef POPPLER_AVAILABLE
    try {
        poppler::document* document = poppler::document::load_from_file(filePath.toStdString());
        if (document && !document->is_locked()) {
            int pages = document->pages();
            delete document;
            return pages;
        }
    } catch (...) {
        // 估算失败，返回默认值
    }
#endif
    return 50; // 默认估算值
}
bool MainWindow::processCompleteFileToCache(const QString& filePath, ProgressDialog* progress, int& currentStep, int totalSteps)
{
    // Martin Fowler重构：使用FileProcessWorker统一处理所有文件类型，注入DPI配置
    DpiConfiguration dpiConfig = getCurrentDpiConfiguration();
    FileProcessWorker* worker = new FileProcessWorker(0, filePath, dpiConfig, this);
    // 同步等待处理完成
    QEventLoop loop;
    connect(worker, &FileProcessWorker::processingFinished, &loop, &QEventLoop::quit);
    connect(worker, &FileProcessWorker::progressUpdated, this, [progress, currentStep, totalSteps](int fileIndex, const UnifiedFileInfo& info) {
        if (progress) {
            int overallProgress = ((currentStep - 1) * 100 + info.progress) / totalSteps;
            progress->setProgress(overallProgress, 100);
        }
    });
    // 启动处理
    QThreadPool::globalInstance()->start(worker);
    // 等待完成
    loop.exec();
        return true;
}
// 已删除：processCompletePDFToCache - 现在使用FileProcessWorker统一处理
// 已删除：processCompleteImageToCache - 现在使用FileProcessWorker统一处理
void MainWindow::loadFileFromCache(const QString& filePath)
{
    // 防止重复调用
    if (m_loadingFile) {
        return;
    }
    // 使用RAII自动管理加载标志
    struct LoadingGuard {
        bool& flag;
        LoadingGuard(bool& f) : flag(f) { flag = true; }
        ~LoadingGuard() { flag = false; }
    } guard(m_loadingFile);
    // 清理所有状态
    m_originalImage = QImage();
    m_imageSplitPositions.clear();
    if (m_pdfDocument) {
        delete m_pdfDocument;
        m_pdfDocument = nullptr;
    }
    // 从缓存获取页数和文件类型
    QString fileIdentity = FileIdentityManager::getFileIdentity(filePath);
    QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
    // 从布局状态管理器获取文件的布局模式
    LayoutStateManager* layoutManager = LayoutStateManager::instance();
    if (!layoutManager) {
        return;
    }
    m_currentMode = layoutManager->getFileLayoutMode(fileIdentity);
    // 详细分析布局状态
    // 检查缓存目录是否存在，如果不存在则创建
    if (!m_cacheManager) {
        return;
    }
    QString baseCacheDir = m_cacheManager->getCacheDirectory();
    QString cacheDir = baseCacheDir + "/" + cacheKey;
    // 确保基础缓存目录存在
    QDir baseDir(baseCacheDir);
    if (!baseDir.exists()) {
        if (!baseDir.mkpath(".")) {
            return;
        }
    } else {
    }
    // 确保文件缓存目录存在
    QDir dir(cacheDir);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            return;
        }
    } else {
    }
    // 计算页面数量
    QStringList files = dir.entryList(QStringList() << "page_*.png", QDir::Files);
    int totalPages = files.size();
    if (totalPages <= 0) {
        // **修复**: 即使没有页面也要初始化视图，等待动态加载
        m_currentFileHash = fileIdentity;
        m_pdfPageCount = 1; // 至少设为1，后续动态扩展
        // 初始化缩略图视图（空状态）
        if (m_virtualThumbnailView) {
            m_virtualThumbnailView->setThumbnailsFromCache(fileIdentity, 1);
            m_virtualThumbnailView->enableProgressiveLoading(true);
        }
        // 初始化主图视图（空状态）
        QList<QImage> emptyPages;
        QImage placeholder = NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中...");
        emptyPages.append(placeholder);
        m_pages = emptyPages;
        if (m_pageView) {
            m_pageView->setPages(m_pages);
        }
        // 文件处理完成是预期行为，无需toast提示
        return;
    }
    // 设置PDF页数（统一处理）
    m_pdfPageCount = totalPages;
    // 使用之前获取的文件标识
    m_currentFileHash = fileIdentity;
    // 为统一内存管理器设置当前文件标识
    if (m_unifiedMemoryManager) {
        auto* manager = static_cast<MinimalUnifiedMemoryManager*>(m_unifiedMemoryManager.get());
        if (manager) {
            manager->setCurrentFileIdentity(fileIdentity);
        }
    }
    // **修复**: 直接设置缩略图视图，不依赖loadThumbnailsFromCache
    if (m_virtualThumbnailView) {
        m_virtualThumbnailView->setThumbnailsFromCache(fileIdentity, totalPages);
    } else {
    }
    // 使用懒加载系统（从缓存加载）
    m_pages = loadPagesLazy(fileIdentity, totalPages);
    // 检查是否需要启用渐进式页面更新
    bool hasPlaceholders = false;
    for (const QImage& page : m_pages) {
        if (NextGenPlaceholder::isPlaceholder(page)) {
            hasPlaceholders = true;
            break;
        }
    }
    if (hasPlaceholders && m_pageView) {
        m_pageView->enableProgressivePageUpdate(true);
        m_pageView->refreshPagesFromCache(fileIdentity);
    }
    // 更新主视图 - 根据处理状态决定更新方式
    if (!m_pages.isEmpty()) {
        if (m_isFileProcessing) {
            // 文件处理中，只更新页面内容，不重置视图
            m_pageView->updatePagesWithoutReset(m_pages);
        } else {
            // 正常情况，使用标准更新方法
            if (!m_pageRenderer) {
                return;
            }
            auto layout = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
            if (!m_pageView) {
                return;
            }
            if (m_currentMode != LayoutMode::SingleColumn) {
                m_pageView->setPages(layout.pages, layout.layoutRects);
            } else {
                m_pageView->setPages(layout.pages);
            }
            // Martin Fowler重构修复：设置全局页码信息以确保显示正确的全局页码
            GlobalPageManager& globalPageManager = GlobalPageManager::instance();
            int globalStartPage = globalPageManager.getFileStartPage(fileIdentity);
            if (globalStartPage > 0) {
                m_pageView->setFileGlobalStartPage(globalStartPage);
                // 设置当前全局页码为文件起始页码
                int currentGlobalPage = globalStartPage;
                globalPageManager.setCurrentGlobalPage(currentGlobalPage);
            } else {
            }
        }
    }
    // 更新状态栏全局页码显示
    if (m_statusBarManager && m_pageView) {
        int currentGlobalPage = m_pageView->getCurrentPageNumber();
        // 使用全局总页数而不是当前文件的页数
        int totalPages = GlobalPageManager::instance().getTotalGlobalPages();
        m_statusBarManager->updateCurrentGlobalPage(currentGlobalPage, totalPages);
    }
    // 显示成功提示
    //showToastMessage(QString("文件加载成功，共 %1 页").arg(totalPages));
}
void MainWindow::singleColumn()
{
    applyLayoutModeToSelectedFiles(LayoutMode::SingleColumn);
}
void MainWindow::twoColumns()
{
    applyLayoutModeToSelectedFiles(LayoutMode::TwoColumns);
}
void MainWindow::threeColumns()
{
    applyLayoutModeToSelectedFiles(LayoutMode::ThreeColumns);
}
void MainWindow::showSystemConfigDialog()
{
    try {
        SystemConfigDialog dialog(this);
        if (dialog.exec() == QDialog::Accepted) {
            SystemConfig config = dialog.getConfig();
            // 应用配置到系统
            applySystemConfig(config);
        } else {
        }
    } catch (const std::exception& e) {
        QMessageBox::critical(this, tr("错误"), tr("系统配置对话框出现异常: %1").arg(e.what()));
    } catch (...) {
        QMessageBox::critical(this, tr("错误"), tr("系统配置对话框出现未知异常"));
    }
}

void MainWindow::showAboutDialog()
{

    AboutDialog* aboutDialog = new AboutDialog(this);

    // 设置当前版本信息
    aboutDialog->setCurrentVersion(m_currentVersion);

    // 如果已有更新信息，设置完整的更新信息
    if (m_hasUpdateAvailable && !m_serverVersion.isEmpty()) {
        aboutDialog->setUpdateInfo(m_serverVersion, m_downloadUrl, m_releaseNotes, m_md5Hash);
    } else if (!m_serverVersion.isEmpty()) {
        // 如果没有完整更新信息，但有服务器版本，使用旧逻辑
        VersionManager::Version current = VersionManager::Version::fromString(m_currentVersion);
        VersionManager::Version server = VersionManager::Version::fromString(m_serverVersion);
        bool updateAvailable = server.isNewerThan(current);
        aboutDialog->setUpdateAvailable(updateAvailable, m_serverVersion);
    }

    // 连接更新检查请求信号 - 使用UpdateChecker而不是UpdateManager
    connect(aboutDialog, &AboutDialog::checkForUpdatesRequested, this, [this]() {
        if (m_updateChecker) {
            m_updateChecker->checkForUpdates(false); // 非静默模式
        } else {
        }
    });

    // 连接显示更新对话框请求信号
    connect(aboutDialog, &AboutDialog::showUpdateDialogRequested, this,
            [this](const QString& version, const QString& downloadUrl, const QString& releaseNotes, const QString& md5) {

        // 创建VersionManager::UpdateInfo对象
        VersionManager::UpdateInfo updateInfo;
        updateInfo.latestVersion = VersionManager::Version::fromString(version);
        updateInfo.updateUrl = downloadUrl;
        updateInfo.updateLog = releaseNotes;
        updateInfo.updateSize = ""; // 可以从UpdateChecker获取
        updateInfo.checksumMD5 = md5;
        updateInfo.forceUpdate = false; // 可以根据需要设置

        // 更新状态栏按钮而不是显示更新对话框
        if (m_statusBarManager) {
            m_statusBarManager->setUpdateButtonState(true);
        }
    });  // 结束showUpdateDialogRequested lambda

    // 连接状态栏按钮更新请求信号
    connect(aboutDialog, &AboutDialog::updateStatusBarButtonRequested, this,
            [this](bool hasUpdate) {
                if (m_statusBarManager) {
                    m_statusBarManager->setUpdateButtonState(hasUpdate);
                }
            });

    // 连接UpdateChecker信号到AboutDialog
    if (m_updateChecker) {

        // 更新可用信号
        connect(m_updateChecker, &UpdateChecker::updateAvailable, aboutDialog,
                [this, aboutDialog](const QString& version, const QString& downloadUrl, const QString& releaseNotes, const QString& md5, const QString& fileSize) {
            // 使用setUpdateInfo设置完整的更新信息，包含下载URL和MD5
            aboutDialog->setUpdateInfo(version, downloadUrl, releaseNotes, md5, fileSize);
        });

        // 无更新信号
        connect(m_updateChecker, &UpdateChecker::noUpdateAvailable, aboutDialog,
                [this, aboutDialog]() {
            aboutDialog->setUpdateAvailable(false, "");
        });

        // 错误信号
        connect(m_updateChecker, &UpdateChecker::checkError, aboutDialog,
                [this, aboutDialog](const QString& error) {
            // 可以显示错误消息框或其他处理
        });

    } else {
    }

    aboutDialog->setAttribute(Qt::WA_DeleteOnClose);
    aboutDialog->exec();

}

// 旧的空实现已移除，使用完整的实现版本
void MainWindow::fitWidth()
{
    if (m_pageView)
        m_pageView->fitWidth();
}
void MainWindow::fitHeight()
{
    if (m_pageView)
        m_pageView->fitHeight();
}
void MainWindow::zoomIn()
{
    if (m_pageView)
        m_pageView->zoomIn();
}
void MainWindow::zoomOut()
{
    if (m_pageView)
        m_pageView->zoomOut();
}

void MainWindow::exportToPdf()
{
    onOneClickExport();
}

void MainWindow::showSystemLoginDialog()
{
    // 如果已经登录，显示用户信息窗口
    if (!LoginDialog::isTrialUser()) {
        // 延迟创建用户信息对话框
        if (!m_userInfoDialog) {
            m_userInfoDialog = new UserInfoDialog(this);
            connect(m_userInfoDialog, &UserInfoDialog::logoutRequested, this, [this]() {
                // 更新登录按钮状态
                updateLoginAction();
                // 更新登录状态指示器（失效）
                updateLoginStatusIndicator(false);
                // 显示退出登录成功消息
                showToastMessage(tr("已退出登录，切换为试用模式"));
                // 对话框关闭后重置指针
                m_userInfoDialog = nullptr;
            });
        }
        m_userInfoDialog->exec();
        return;
    }

    LoginDialog loginDialog(this);

    // 如果有自动登录的token，先尝试自动登录
    if (loginDialog.autoLoginAtStartup()) {
        updateLoginAction();
        // 更新登录状态指示器（有效）
        updateLoginStatusIndicator(true);
        // 移除自动登录成功提示toast
        return;
    }

    if (loginDialog.exec() == QDialog::Accepted) {
        // 登录成功
        updateLoginAction();

        // 更新登录状态指示器（有效）
        updateLoginStatusIndicator(true);

        // 移除登录成功提示toast
        // QString welcomeMsg;
        // if (LoginDialog::isTrialUser()) {
        //     welcomeMsg = tr("登录成功 - 试用版");
        // } else {
        //     welcomeMsg = tr("登录成功 - 付费版");
        // }
        // showToastMessage(welcomeMsg);

        // 保存登录状态到ConfigManager（使用新的authToken系统）
        // ConfigManager::setUserToken() 保持向后兼容
        ConfigManager::setUserToken(loginDialog.token());
        ConfigManager::setUserEmail(loginDialog.email());
        ConfigManager::setAuthToken(loginDialog.token()); // 新的Token管理系统
        ConfigManager::sync();

        // 如果是付费用户，可以添加一些额外功能
        if (!LoginDialog::isTrialUser()) {
            // 启用付费用户功能
            enablePremiumFeatures();
        }
    }
}

void MainWindow::updateLoginAction()
{
    if (LoginDialog::isTrialUser()) {
        m_systemLoginAction->setText(tr("登录"));
        m_systemLoginAction->setStatusTip("");  // 移除状态条提示
    } else {
        m_systemLoginAction->setText(tr("已登录"));
        m_systemLoginAction->setStatusTip("");  // 移除状态条提示
    }
}

void MainWindow::enablePremiumFeatures()
{
    // 启用付费用户的高级功能
    // 例如：移除水印、解锁高分辨率导出、批量处理等

    // 这里可以根据需要启用相应的UI元素或功能
    
    // 可以在这里添加更多付费功能的启用逻辑
}

void MainWindow::initializeLoginStatus()
{

    // 确保ConfigManager已初始化并执行配置迁移
    ConfigManager::initialize();
    ConfigManager::migrateFromUserIni();

    // 从ConfigManager读取登录信息
    QString token = ConfigManager::getUserToken();
    QString userEmail = ConfigManager::getUserEmail();

    bool hasToken = !token.isEmpty();
    bool hasEmail = !userEmail.isEmpty();


    if (hasToken && hasEmail) {
        // 有保存的登录信息，尝试验证token有效性

        // 创建LoginDialog实例进行自动登录验证
        LoginDialog loginDialog(this);
        if (loginDialog.autoLoginAtStartup()) {
            // 自动登录成功
            updateLoginAction();
            // 更新登录状态指示器（有效）
            updateLoginStatusIndicator(true);
            // 移除自动登录成功提示toast
            return;
        } else {
            // 自动登录失败，设置为试用用户
            LoginDialog::updateUserStatus(true);   // true表示试用用户
        }
    } else {
        // 没有登录信息，设置为试用用户
        LoginDialog::updateUserStatus(true);   // true表示试用用户
    }

    // 更新登录按钮状态
    updateLoginAction();

    // 初始化登录状态指示器
    // 检查是否有有效的Token来决定初始状态
    bool hasValidToken = !ConfigManager::getAuthToken().isEmpty();
    updateLoginStatusIndicator(hasValidToken);
}

// 包装方法实现，检查文件列表状态
void MainWindow::safeSingleColumn()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        singleColumn();
    }
}

void MainWindow::safeTwoColumns()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        twoColumns();
    }
}

void MainWindow::safeThreeColumns()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        threeColumns();
    }
}

void MainWindow::safeFitWidth()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        fitWidth();
    }
}

void MainWindow::safeFitHeight()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        fitHeight();
    }
}

void MainWindow::safeZoomIn()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        zoomIn();
    }
}

void MainWindow::safeZoomOut()
{
    if (m_fileBrowser && !m_fileBrowser->getFiles().isEmpty()) {
        zoomOut();
    }
}

void MainWindow::notifyUserActivity()
{
    // Martin Fowler重构：移除onUserActivity调用（呼吸灯已删除）
}

bool MainWindow::eventFilter(QObject* obj, QEvent* event)
{
    // 检测用户活动事件
    switch (event->type()) {
        case QEvent::MouseMove:
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::KeyPress:
        case QEvent::Wheel:
            notifyUserActivity();
            break;
        default:
            break;
    }
    
    return QMainWindow::eventFilter(obj, event);
}

bool MainWindow::hasFilesForExport() const
{
    if (m_fileBrowser) {
        auto files = m_fileBrowser->getFiles();
        bool hasFiles = !files.isEmpty();
        return hasFiles;
    }
    return false;
}

bool MainWindow::isFileProcessing() const
{
    if (!m_fileBrowser) {
        return false;
    }
    
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (files.isEmpty()) {
        return false;
    }
    
    // 检查是否有文件正在处理中
    for (const auto& file : files) {
        if (file.processStatus == FileProcessStatus::Processing) {
            return true;
        }
    }
    
    return false;
}
void MainWindow::createUpdateAction()
{
    m_checkUpdateAction = new QAction(tr("使用在线版"), this);
    connect(m_checkUpdateAction, &QAction::triggered,
            this, [this]() { openOnlineVersion(); });
}
void MainWindow::openOnlineVersion()
{
    QDesktopServices::openUrl(QUrl("https://ctdy123.com"));
}

void MainWindow::checkForUpdates(bool silent)
{
    if (m_updateManager) {
        m_updateManager->checkForUpdates(silent);
    }
}
void MainWindow::createLanguageMenu()
{
    // 直接使用已创建的动作
    m_languageMenu = menuBar()->addMenu(tr("Language"));
    m_languageMenu->setObjectName("languageMenu");
    QActionGroup* languageGroup = new QActionGroup(this);
    languageGroup->addAction(m_englishAction);
    languageGroup->addAction(m_chineseSimplifiedAction);
    m_languageMenu->addActions(languageGroup->actions());
    // 根据保存的语言设置选中状态
    
    QString savedLanguage = ConfigManager::getLanguage();
    if (savedLanguage == "en") {
        m_englishAction->setChecked(true);
    } else {
        m_chineseSimplifiedAction->setChecked(true);
    }
}
void MainWindow::switchLanguage(const QString& language)
{
    if (m_currentLanguage != language) {
        // 加载新语言
        loadLanguage(language);
        m_currentLanguage = language;
        // 保存语言设置
        
        ConfigManager::setLanguage(language);
        ConfigManager::sync();  // 确保设置立即写入
        // 更新界面元素
        updateActionTexts();
        updateMenuTexts();
        // 更新工具栏标题
        if (m_mainToolBar) {
            m_mainToolBar->setWindowTitle(tr("工具栏"));
        }
        // 更新语言菜单选中状态
        if (m_englishAction && language == "en") {
            m_englishAction->setChecked(true);
        } else if (m_chineseSimplifiedAction && language == "zh_CN") {
            m_chineseSimplifiedAction->setChecked(true);
        }
        // 更新其他UI元素
        if (m_pageView) {
            m_pageView->retranslateUi();
        }
        if (m_thumbnailView) {
            m_thumbnailView->retranslateUi();
        }
    }
}
void MainWindow::loadLanguage(const QString& locale)
{
    // 移除旧的翻译器
    if (m_translator) {
        qApp->removeTranslator(m_translator);
        delete m_translator;
    }
    // 创建新的翻译器
    m_translator = new QTranslator(this);
    QString qmFile;
    // 根据语言代码选择对应的翻译文件
    if (locale == "zh_CN") {
        qmFile = ":/translations/LongImageReader_ZH_CN.qm";
    } else if (locale == "en") {
        qmFile = ":/translations/LongImageReader_en.qm";
    }
    if (!qmFile.isEmpty() && m_translator->load(qmFile)) {
        qApp->installTranslator(m_translator);
        // 更新所有窗口部件的语言环境
        QList<QWidget*> widgets = QApplication::allWidgets();
        for (QWidget* widget : widgets) {
            widget->setLocale(QLocale(locale));
        }
        // 触发重新翻译事件
        QEvent *event = new QEvent(QEvent::LanguageChange);
        QApplication::postEvent(this, event);
    }
}
QString MainWindow::getCurrentLanguage() const
{
    return m_currentLanguage; // 直接返回成员变量
}
void MainWindow::saveLanguageSetting(const QString& locale)
{
    
    ConfigManager::setLanguage(locale);
    m_currentLanguage = locale; // 更新成员变量
}
// 旧的handleUpdateAvailable方法已被新的onUpdateAvailable方法替代
void MainWindow::handleNoUpdate()
{
    QMessageBox::information(this,
        tr("检查更新"),
        tr("您使用的已经是最新版本。"));
}
// 旧的UpdateChecker相关方法已被UpdateManager替代
bool MainWindow::event(QEvent *event)
{
    if (event->type() == QEvent::LanguageChange) {
        // 只更新文本，不重新建UI元素
        updateActionTexts();    // 更新动作文本
        updateMenuTexts();      // 更新菜单文本
        if (m_mainToolBar) {
            m_mainToolBar->setWindowTitle(tr("工具栏"));
        }
        return true;
    }
    return QMainWindow::event(event);
}
// 新增函数用于更新作文本
void MainWindow::updateActionTexts()
{
    // 文件相关动作
    m_loadAction->setText(tr("打开"));
    // 列显示动作
    singleColumnAct->setText(tr("单栏显示"));
    twoColumnsAct->setText(tr("双栏显示"));
    threeColumnsAct->setText(tr("三栏显示"));
    // PDF导出动作
    // PDF导出动作文本设置已移除
    // 系统配置动作
    m_systemConfigAction->setText(tr("系统配置"));
    // 缩相关动作
    m_fitWidthAction->setText(tr("适合宽度"));
    m_fitHeightAction->setText(tr("适合高度"));
    m_zoomInAction->setText(tr("放大"));
    m_zoomOutAction->setText(tr("缩小"));
    // 导入导出动作
    m_loadAction->setText(tr("导入文件..."));
    m_exportAction->setText(tr("导出为PDF..."));
    // 批处理动作
    // 更新检查动作
    m_checkUpdateAction->setText(tr("使用在线版"));
    // 关于动作
    m_aboutAction->setText(tr("关于"));
    // 退出动作
    m_exitAction->setText(tr("退出"));
    // 语言菜单动作
    m_englishAction->setText(tr("English"));
    m_chineseSimplifiedAction->setText(tr("简体中文"));
}
// 新增函数用于更新菜单文本
void MainWindow::updateMenuTexts()
{
    // 所有菜单
    QList<QMenu*> menus = menuBar()->findChildren<QMenu*>();
    // 更新菜单题
    for (QMenu* menu : menus) {
        QString objectName = menu->objectName();
        if (objectName == "fileMenu") {
            menu->setTitle(tr("文件"));
        } else if (objectName == "viewMenu") {
            menu->setTitle(tr("视图"));
        } else if (objectName == "helpMenu") {
            menu->setTitle(tr("帮助"));
        } else if (objectName == "languageMenu") {
            menu->setTitle(tr("语言"));
        }
    }
    // 更新缩略图视图的文本
    if (m_thumbnailView) {
        m_thumbnailView->retranslateUi();
    }
}
void MainWindow::checkLicense()
{
    if (!LicenseManager::instance().isLicensed()) {
        QMessageBox::warning(this, tr("未注册版本"),
            tr("您正在使用未注册版本。导出的文件将包含水印。\n"
               "请购买授权以移除水印并支持开发者。"));
    } else if (!LicenseManager::instance().checkDeviceLimit()) {
        QMessageBox::warning(this, tr("设备数量超限"),
            tr("当前授权的设备数量已达到上限(3台)。\n"
               "请在其他设备上停用后再试。"));
    }
}
// 实现拖放事件处理函数
void MainWindow::dragEnterEvent(QDragEnterEvent* event)
{
    // Martin Fowler Extract Method重构：使用统一拖拽处理器
    if (m_dragDropHandler && m_dragDropHandler->handleDragEnter(event)) {
        return; // 事件已被处理器接受
    }
    event->ignore();
}
void MainWindow::dropEvent(QDropEvent* event)
{
    // Martin Fowler Extract Method重构：使用统一拖拽处理器和智能布局
    if (!m_dragDropHandler) {
        event->ignore();
        return;
    }
    // 获取现有文件列表用于重复检测
    QList<UnifiedFileInfo> existingFiles;
    if (m_fileBrowser) {
        existingFiles = m_fileBrowser->getFiles();
    }
    // Martin Fowler Refactor: 使用增强的拖拽处理器，包含重复文件检测
    m_dragDropHandler->handleDrop(event, 
        [this](const UnifiedDragDropHandler::DragDropResult& result) {
            handleDragDropResult(result);
        }, 
        existingFiles,
        UnifiedDragDropHandler::DuplicateStrategy::Skip); // 默认跳过重复文件
}
// === 新增：拖拽重复文件处理方法 ===
void MainWindow::handleDragDropResult(const UnifiedDragDropHandler::DragDropResult& result)
{
    // 显示重复文件提示
    if (result.hasDuplicates()) {
        showDuplicateFileNotification(result.duplicateFiles, result.duplicateMapping);
    }
    // 只添加非重复的有效文件
    if (result.hasValidFiles()) {
        m_fileBrowser->addFiles(result.validFiles);
        // 显示文件列表（宽度由visibilityChanged信号自动处理）
        m_fileBrowserDock->show();
        m_toggleLeftSidebarAction->setChecked(true);
        
        // 显示预览面板，设置宽度为220px
        m_thumbnailDock->show();
        m_toggleRightSidebarAction->setChecked(true);
        m_thumbnailDock->resize(220, m_thumbnailDock->height());
        // 开始后台处理文件（智能布局将在文件处理完成后异步应用）
        startFileProcessing();
        // 文件添加成功是预期行为，无需toast提示
    } else if (result.hasDuplicates() && !result.hasValidFiles()) {
        // 只有重复文件，没有新文件
        // 重复文件跳过是预期行为，无需toast提示
    } else {
        // 没有任何有效文件
        // 无效文件情况通过其他方式反馈，无需toast提示
    }
}
void MainWindow::showDuplicateFileNotification(const QStringList& duplicateFiles,
                                              const QHash<QString, QString>& duplicateMapping)
{
    if (duplicateFiles.isEmpty()) {
        return;
    }
    QString message;
    if (duplicateFiles.size() == 1) {
        QFileInfo fileInfo(duplicateFiles.first());
        message = QString("文件已存在，已跳过");
    } else {
        message = QString("发现 %1 个重复文件，已跳过")
                 .arg(duplicateFiles.size());
    }
    // 使用非阻塞式提示
    showToastMessage(message);
    // 在控制台输出详细信息
    for (const QString& duplicateFile : duplicateFiles) {
        QString existingFile = duplicateMapping.value(duplicateFile, "未知");
    }
}
void MainWindow::showEvent(QShowEvent* event)
{
    QMainWindow::showEvent(event);
    emit windowShown();
}
// 文件列表相关槽函数实现
void MainWindow::onFileSelected(int index, const UnifiedFileInfo& file)
{
    Q_UNUSED(index)
    // 输出当前GlobalPageManager中所有文件的起始页码
    QString debugInfo = GlobalPageManager::instance().getDebugInfo();
    QStringList lines = debugInfo.split('\n');
    for (const QString& line : lines) {
        if (!line.isEmpty()) {
        }
    }
    // 将当前选择的文件同步到统一状态管理器
    if (!file.fileIdentity.isEmpty()) {
        LayoutStateManager::instance()->setCurrentFile(file.fileIdentity);
    }
    // === Martin Fowler重构：使用连续分页方法切换文件 ===
    // 使用文件标识而不是文件路径，支持全局页码连续性
    if (!file.fileIdentity.isEmpty()) {
        switchToFileWithContinuousPaging(file.fileIdentity);
    } else {
        // 回退到传统方法
        loadFileFromCache(file.filePath);
    }
}
void MainWindow::onFileRemoved(int index)
{
    // === Martin Fowler重构：完整的文件移除处理 ===
    clearFileFromAllComponents(index);
    // 文件删除后，需要检查是否需要切换到新的当前文件
    if (m_fileBrowser) {
        int newCurrentIndex = m_fileBrowser->getCurrentIndex();
        int totalFiles = m_fileBrowser->getFileCount();
        if (totalFiles > 0 && newCurrentIndex >= 0) {
            // 还有文件，自动切换到新的当前文件
            UnifiedFileInfo newCurrentFile = m_fileBrowser->getFile(newCurrentIndex);
            if (!newCurrentFile.filePath.isEmpty()) {
                // 通过发送fileSelected信号触发主窗口切换
                emit m_fileBrowser->fileSelected(newCurrentIndex, newCurrentFile);
            }
        } else {
            // 没有文件了，重置到初始状态
            resetUIToInitialState();
        }
    }
    // 更新状态栏显示
    updateStatusBarFileInfo();
}
void MainWindow::onFilesChanged()
{
    // === Martin Fowler重构：统一状态管理 ===
    if (m_fileBrowser) {
        int totalFiles = m_fileBrowser->getFileCount();
        int currentIndex = m_fileBrowser->getCurrentIndex();
        if (totalFiles == 0) {
            // 所有文件都被删除，重置到初始状态
            resetUIToInitialState();
        } else if (currentIndex >= 0) {
            // 有文件且有选中，确保主窗口显示正确
            UnifiedFileInfo currentFile = m_fileBrowser->getFile(currentIndex);
            if (!currentFile.filePath.isEmpty()) {
                // 检查当前显示的文件是否与选中文件一致
                QString currentDisplayedHash = m_currentFileHash;
                QString selectedFileHash = FileIdentityManager::getFileIdentity(currentFile.filePath);
                if (currentDisplayedHash != selectedFileHash) {
                    loadFileFromCache(currentFile.filePath);
                }
            }
        }
    }
    // 更新侧边栏显示状态（仅在初始化完成后）
    if (m_initializationComplete) {
        // 不再管理侧边栏状态
    }
    // 更新状态栏显示
    updateStatusBarFileInfo();
}
void MainWindow::onFilesReordered()
{
    // 文件顺序变化时的处理逻辑（拖拽排序、移到顶部/底部等）
    // 如果当前有选中的文件，重新加载以反映新的顺序
    if (m_fileBrowser && m_fileBrowser->getCurrentIndex() >= 0) {
        int currentIndex = m_fileBrowser->getCurrentIndex();
        // **重要修复**: 创建文件列表的安全副本，避免use-after-free
        QList<UnifiedFileInfo> filesCopy = m_fileBrowser->getFiles();
        if (currentIndex < filesCopy.size()) {
            const UnifiedFileInfo& currentFile = filesCopy[currentIndex];
            // 检查文件路径是否有效
            if (!currentFile.filePath.isEmpty() && QFile::exists(currentFile.filePath)) {
                loadFileFromCache(currentFile.filePath);
            } else {
            }
        }
    }
}
void MainWindow::onSettingsChanged(int index, const UnifiedFileInfo& settings)
{
    Q_UNUSED(index)
    Q_UNUSED(settings)
    // 文件设置变化时的处理逻辑
}
void MainWindow::onExportRequested()
{
    // 从文件列表导出PDF的请求
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (files.isEmpty()) {
        showToastMessage(tr("没有文件可以导出"));
        return;
    }
    // 使用文件列表中的文件设置创建批量PDF生成器
    // 这里需要将FileInfo转换为FileSettings
    // 暂时使用现有的批量PDF生成器
}
void MainWindow::onPreviewRequested(int index, const UnifiedFileInfo& file)
{
    // 通知文件列表更新主窗口当前文件索引
    if (m_fileBrowser) {
        m_fileBrowser->setMainWindowCurrentFile(index);
    }
    // 直接使用文件路径从缓存加载
    loadFileFromCache(file.filePath);
}
void MainWindow::onClearAllRequested()
{
    // Martin Fowler Extract Method: 分解为职责单一的清理方法
    clearMemoryData();
    clearDiskCache();
    clearProgramStates();
    resetUIToInitialState();
}
void MainWindow::clearMemoryData()
{
    // 清理PDF文档
    if (m_pdfDocument) {
        delete m_pdfDocument;
        m_pdfDocument = nullptr;
    }
    // 清理图像数据
    m_originalImage = QImage();
    // 清理任务映射
    m_taskToFileIndex.clear();
    // 清理当前文件标识
    m_currentFileHash.clear();
}
void MainWindow::clearDiskCache()
{
    // 通过统一缓存管理器清理所有缓存
    UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
    if (cacheManager) {
        cacheManager->clearAllCache();
    }
    // === Martin Fowler重构：增强缓存清理 ===
    // 清理内存缓存管理器
    MemoryCacheManager* memoryCache = MemoryCacheManager::instance();
    if (memoryCache) {
        // 重置内存缓存统计
        memoryCache->resetMetrics();
        // 注意：MemoryCacheManager会通过LRU自动清理，无需手动清除
    }
    // 清理缩略图视图的内存缓存
    if (m_virtualThumbnailView) {
        // 清空缩略图数据
        m_virtualThumbnailView->clear();
        // 重置缩略图视图状态
        if (m_fileBrowser) {
            m_virtualThumbnailView->setThumbnails(QList<QImage>());
        }
    }
    // 清理页面视图的内存缓存
    if (m_pageView) {
        // 页面视图会通过统一内存管理器处理缓存
    }
}
void MainWindow::clearProgramStates()
{
    // 重置布局状态管理器
    LayoutStateManager::instance()->clearAllStates();
    // 重置统一线程管理器
    // UnifiedThreadManager::instance()->clearAllTasks(); // 方法不存在，暂时注释
}
// === Martin Fowler重构：Extract Method - 完整的文件移除清理 ===
void MainWindow::clearFileFromAllComponents(int removedIndex)
{
    // 1. 清理PageView显示内容（如果当前显示的是被删除的文件）
    if (m_pageView) {
        // 检查当前显示的文件是否是被删除的文件
        QString currentDisplayedFile = m_currentFileHash;
        if (!currentDisplayedFile.isEmpty()) {
            // 如果当前显示的是被删除的文件，清空显示
            m_pageView->setPages(QList<QImage>());
            m_currentFileHash.clear();
        }
    }
    // 2. 清理缩略图视图（VirtualThumbnailView）
    if (m_virtualThumbnailView) {
        // 完全清空缩略图视图，包括占位符
        m_virtualThumbnailView->setThumbnails(QList<QImage>());
    }
    // 3. 清理传统缩略图视图（如果存在）
    if (m_thumbnailView) {
        // 完全清空传统缩略图视图
        m_thumbnailView->setPages(QList<QImage>());
    }
    // 4. 清理预加载器中相关的任务
    // 如果有BackgroundLoader或PreloadController的引用，在这里清理
    // TODO: 添加预加载器清理逻辑（如果需要）
    }
void MainWindow::resetUIToInitialState()
{
    // === Martin Fowler重构：完整的UI状态重置 ===
    // 1. 清空页面视图
    if (m_pageView) {
        m_pageView->setPages(QList<QImage>());
    }
    // 2. 清空缩略图视图
    if (m_virtualThumbnailView) {
        // 完全清空缩略图视图，包括占位符
        m_virtualThumbnailView->setThumbnails(QList<QImage>());
    }
    if (m_thumbnailView) {
        // 完全清空传统缩略图视图
        m_thumbnailView->setPages(QList<QImage>());
    }
    // 3. 重置当前文件状态
    m_currentFileHash.clear();
    // 注意：MainWindow没有m_currentPageIndex成员变量，使用m_savedCurrentPage
    m_savedCurrentPage = -1;
    // 4. 重置窗口标题
    setWindowTitle(tr("LimeReader - 影谷长图处理大师"));
    // 5. 重置状态栏显示
    updateStatusBarFileInfo();

    // 6. 更新欢迎信息显示
    updateWelcomeMessage();
    // 6. 不再管理侧边栏状态
    // updateSidebarVisibility() 已删除
    // 7. 清理工具栏状态（如果有文件相关的工具栏状态）
    // TODO: 根据具体的工具栏实现添加重置逻辑
    // 8. 重置设置面板状态
    if (m_settingsWidget) {
        // 清理设置面板中可能的文件相关状态
        m_settingsWidget->onFileListChanged();
    }
    }
void MainWindow::onResetProgramRequested()
{
    // 显示确认对话框
    QMessageBox::StandardButton reply = QMessageBox::question(
        this,
        tr("重置程序"),
        tr("确定要清除所有文件并重置程序吗？这将清理所有内存缓存和窗口显示，回到最初状态。"),
        QMessageBox::Yes | QMessageBox::No,
        QMessageBox::No
    );
    if (reply == QMessageBox::Yes) {
        // Martin Fowler DRY原则：复用已重构的清理方法
        clearMemoryData();
        clearDiskCache();
        clearProgramStates();
        resetUIToInitialState();
    }
}
// Martin Fowler Extract Method: 分解清理逻辑的具体实现
bool MainWindow::loadImageFile(const QString& filePath, QImage& image)
{
    QImageReader reader(filePath);
    // 检查文件是否支持
    if (!reader.canRead()) {
        return false;
    }
    // 设置读取选项
    reader.setAutoTransform(true); // 自动应用EXIF方向
    reader.setDecideFormatFromContent(true); // 从内容决定格式
    // 为超长/超高图片放宽内存限制（Qt6 默认约 128MB）
    QSize sz = reader.size();
    if (sz.isValid()) {
        qint64 bytes = qint64(sz.width()) * qint64(sz.height()) * 4; // 估算32位像素
        int needMB = int((bytes + (1<<20) - 1) >> 20);
        int limitMB = qMax(256, needMB + 32); // 预留余量
        QImageReader::setAllocationLimit(limitMB);
    } else {
        QImageReader::setAllocationLimit(1024); // 兜底1GB
    }
    // 显示进度对话框
    QProgressDialog progress(tr("正在加载图片..."), tr("取消"), 0, 0, this);
    progress.setWindowModality(Qt::WindowModal);
    progress.setMinimumDuration(500); // 500ms后显示
    progress.setValue(0);
    progress.show();
    // 允许UI更新
    QApplication::processEvents();
    // 尝试读取图片
    image = reader.read();
    // 如果第一次读取失败，尝试不同的方法
    if (image.isNull()) {
        // 重置reader
        reader.setDevice(nullptr);
        reader.setFileName(filePath);
        // 尝试不设置自动变换
        reader.setAutoTransform(false);
        image = reader.read();
        if (image.isNull()) {
            // 尝试从文件直接读取
            QFile file(filePath);
            if (file.open(QIODevice::ReadOnly)) {
                QByteArray data = file.readAll();
                file.close();
                if (!data.isEmpty()) {
                    image.loadFromData(data);
                }
            }
        }
    }
    progress.close();
    if (image.isNull()) {
        return false;
    }
    return true;
}
void MainWindow::debugOutput(const QString& /*message*/) const
{
    // 日志功能已关闭：不输出调试信息
}
// 已删除：loadPDFPage - 现在使用统一的缓存加载
void MainWindow::addToCache(int pageIndex, const QImage& image)
{
    // 如果缓存已满，移除最旧的页面
    if (m_loadedPages.size() >= getMaxPagesInMemory()) {
        int oldestIndex = m_loadedPageIndices.first();
        m_loadedPageIndices.removeFirst();
        m_loadedPages.removeFirst();
    }
    // 添加到缓存
    m_loadedPageIndices.append(pageIndex);
    m_loadedPages.append(image);
}
void MainWindow::clearPDFCache()
{
    m_loadedPages.clear();
    m_loadedPageIndices.clear();
}
void MainWindow::updatePDFViews()
{
    try {
        // 创建虚拟页面列表（用于显示页码）
        QList<QImage> virtualPages;
        for (int i = 0; i < m_pdfPageCount; i++) {
            int cacheIndex = m_loadedPageIndices.indexOf(i);
            if (cacheIndex >= 0) {
                // 已加载的页面
                if (cacheIndex < m_loadedPages.size()) {
                    virtualPages.append(m_loadedPages[cacheIndex]);
                } else {
                    // 创建占位符
                    virtualPages.append(QImage(100, 100, QImage::Format_RGB32));
                }
            } else {
                // 未加载的页面，创建占位符
                QImage placeholder(100, 100, QImage::Format_RGB32);
                placeholder.fill(Qt::lightGray);
                virtualPages.append(placeholder);
            }
        }
        // 更新视图
        m_pageView->setPages(virtualPages);
        // 更新虚拟滚动缩略图
        if (m_virtualThumbnailView) {
            m_virtualThumbnailView->setThumbnails(virtualPages);
        }
        m_pageView->setCurrentPage(0);
    } catch (const std::exception& e) {
        QMessageBox::warning(this, tr("错误"), 
            tr("更新PDF视图时发生错误：%1").arg(e.what()));
    } catch (...) {
        QMessageBox::warning(this, tr("错误"), 
            tr("更新PDF视图时发生未知错误"));
    }
}
void MainWindow::showToastMessage(const QString& message) const
{
    // 使用统一的ToastNotification系统
    ToastNotification::showInfo(const_cast<MainWindow*>(this), message);
}
void MainWindow::onThumbnailSelected(int index)
{
    // 更新页面视图到选中的页面
    if (m_pageView && index >= 0 && index < m_pages.size()) {
        m_pageView->setCurrentPage(index);
    }
}
void MainWindow::onThumbnailClicked(int index)
{
    navigateAndHighlight(index, NavigationIntent::FromVirtualThumbnail);
}
void MainWindow::handleThumbnailClickInternal(int index)
{
    // 更新页面视图到对应的组合页面
    if (m_pageView && index >= 0) {
        if (m_isFileProcessing) {
            // **处理状态下的特殊逻辑**: 只跳转到已加载的真实页面
            // 检查目标页面是否已加载（不是占位符）
            if (index < m_pages.size()) {
                const QImage& targetPage = m_pages[index];
                bool isLoaded = NextGenPlaceholder::isRealContent(targetPage);
                if (isLoaded) {
                    // 页面已加载，直接跳转
                    m_pageView->setCurrentPage(index);
                } else {
                    // 页面未加载，显示提示
                    // 可以在这里显示一个提示，告诉用户页面正在加载中
                }
            } else {
            }
        } else {
            // **正常状态**: 使用修复后的映射逻辑
            int pagesPerComposite = m_unifiedRenderer->pagesPerComposite(m_currentMode);
            // **重要修复**: 区分原始页面索引和组合页面索引
            int originalPageIndex = index;  // 缩略图索引直接对应原始页面索引
            int compositePageIndex = mapThumbnailToMainPage(index);  // 计算组合页面索引
            // === 立即反馈：先跳转并设置高亮，避免等待加载期间没有视觉反馈 ===
            if (m_pageView) {
                m_pageView->setShouldCenterOnUpdate(true);
                // 修复：compositePageIndex是组合页面索引，需要转换为原始页面索引
                int originalPageIndex = compositePageIndex * pagesPerComposite;
                if (originalPageIndex >= 0 && originalPageIndex < m_pageView->pageCount()) {
                    m_pageView->setCurrentPage(originalPageIndex);
                }
                if (m_currentMode != LayoutMode::SingleColumn) {
                    int totalThumbnails = m_virtualThumbnailView ? m_virtualThumbnailView->count()
                                                                : (m_thumbnailView ? m_thumbnailView->count() : m_pages.size());
                    int columnMode = static_cast<int>(m_currentMode);
                    m_pageView->setHighlightedThumbnail(index, totalThumbnails, columnMode);
                }
            }
            // 计算该组合页面包含的原始页面范围
            int compositeStartIndex = compositePageIndex * pagesPerComposite;
            int compositeEndIndex = qMin(compositeStartIndex + pagesPerComposite, m_pages.size());
            // **优先加载目标页面**: 确保点击的目标页面立即可用
            bool targetPageLoaded = false;
            // 第一步：优先同步加载目标原始页面
            if (originalPageIndex >= 0 && originalPageIndex < m_pages.size()) {
                const QImage& targetPage = m_pages[originalPageIndex];
                if (NextGenPlaceholder::isPlaceholder(targetPage)) {
                    QImage cachedPage = loadPageFromUnifiedCache(originalPageIndex);
                    if (!cachedPage.isNull() && !NextGenPlaceholder::isPlaceholder(cachedPage)) {
                        m_pages[originalPageIndex] = cachedPage;
                        targetPageLoaded = true;
                        // **关键修复**: 立即更新视图，确保用户看到真实内容
                        auto layoutNow = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                        m_pageView->updatePagesWithoutReset(layoutNow.pages);
                        if (m_currentMode != LayoutMode::SingleColumn) {
                            m_pageView->setAccurateLayoutRects(layoutNow.layoutRects);
                        }
                    }
                } else {
                    targetPageLoaded = true; // 已经是真实内容
                }
            }
            // 第二步：批量从缓存加载同组合页面的其他页面
            bool batchLoadSuccess = false;
            for (int i = compositeStartIndex; i < compositeEndIndex; ++i) {
                if (i == originalPageIndex) continue; // 跳过已处理的目标页面
                if (i >= m_pages.size()) {
                    // 扩展页面数组
                    while (m_pages.size() <= i) {
                        m_pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中..."));
                    }
                }
                const QImage& currentPage = m_pages[i];
                if (NextGenPlaceholder::isPlaceholder(currentPage)) {
                    QImage cachedPage = loadPageFromUnifiedCache(i);
                    if (!cachedPage.isNull() && !NextGenPlaceholder::isPlaceholder(cachedPage)) {
                        m_pages[i] = cachedPage;
                        batchLoadSuccess = true;
                    }
                }
            }
            // **时序优化**: 批量加载完成后统一更新视图
            if (batchLoadSuccess) {
                auto layoutBatch = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                m_pageView->updatePagesWithoutReset(layoutBatch.pages);
                if (m_currentMode != LayoutMode::SingleColumn) {
                    m_pageView->setAccurateLayoutRects(layoutBatch.layoutRects);
                }
            }
            // 检查目标原始页面是否已加载
            bool pageLoaded = false;
            if (originalPageIndex < m_pages.size()) {
                const QImage& targetPage = m_pages[originalPageIndex];
                bool isPlaceholder = NextGenPlaceholder::isPlaceholder(targetPage);
                if (!isPlaceholder) {
                    pageLoaded = true;
                } else if (targetPageLoaded) {
                    pageLoaded = true;
                } else {
                    if (!m_toastShown) {
                        // 文件处理是常态，减少干扰提示
                        m_toastShown = true;
                        QTimer::singleShot(TOAST_MEDIUM_MS, this, [this]() { m_toastShown = false; });
                    }
                }
            } else {
                // **修复**: 当目标原始页面索引超出 m_pages 范围时，尝试从缓存加载
                // 首先扩展 m_pages 到足够的大小
                if (originalPageIndex >= m_pages.size()) {
                    int neededSize = originalPageIndex + 1;
                    while (m_pages.size() < neededSize) {
                        m_pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中..."));
                    }
                }
                // 然后从缓存加载目标页面
                QImage cachedPage = loadPageFromUnifiedCache(originalPageIndex);
                if (!cachedPage.isNull()) {
                    // 使用修复后的检测逻辑
                    bool isValidSize = cachedPage.width() > 200 && cachedPage.height() > 200;
                    bool isPlaceholderImage = NextGenPlaceholder::isPlaceholder(cachedPage);
                    bool isRealContentFromCache = isValidSize && !isPlaceholderImage;
                    if (isRealContentFromCache) {
                        // 更新页面内容
                        m_pages[originalPageIndex] = cachedPage;
                        pageLoaded = true;
                        targetPageLoaded = true; // 标记目标页面已加载
                        // **关键修复**: 立即更新主视图，确保用户立即看到真实内容
                        auto layoutNow2 = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                        m_pageView->updatePagesWithoutReset(layoutNow2.pages);
                        if (m_currentMode != LayoutMode::SingleColumn) {
                            m_pageView->setAccurateLayoutRects(layoutNow2.layoutRects);
                        }
                    } else {
                    }
                } else {
                }
            }
            // **改进的页面更新和跳转逻辑**
            if (pageLoaded || targetPageLoaded) {
                // **时序优化**: 只有在之前没有批量更新或者需要最终确认时才更新
                auto layoutAfter = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                // **时序控制**: 统一的最终视图更新
                if (!batchLoadSuccess || targetPageLoaded) {
                    m_pageView->updatePagesWithoutReset(layoutAfter.pages);
                } else {
                }
                // **修复**: 使用正确的组合页面索引（不再需要重新计算）
                int targetCompositeIndex = compositePageIndex;
                // **新增防护机制**: 在跳转前验证目标页面状态
                bool canSafelyJump = true;
                if (m_currentMode != LayoutMode::SingleColumn && targetCompositeIndex < layoutAfter.pages.size()) {
                    const QImage& targetCompositeImage = layoutAfter.pages[targetCompositeIndex];
                    if (NextGenPlaceholder::isPlaceholder(targetCompositeImage)) {
                        canSafelyJump = false;
                    }
                } else if (m_currentMode == LayoutMode::SingleColumn && originalPageIndex < m_pages.size()) {
                    const QImage& targetOriginalImage = m_pages[originalPageIndex];
                    if (NextGenPlaceholder::isPlaceholder(targetOriginalImage)) {
                        canSafelyJump = false;
                    }
                }
                // 延迟执行跳转，确保页面更新完成
                QTimer::singleShot(NAVIGATE_DELAY_MS, this, [this, targetCompositeIndex, originalPageIndex, index, canSafelyJump]() {
                    if (m_pageView && targetCompositeIndex >= 0 && targetCompositeIndex < m_pageView->pageCount()) {
                        if (!canSafelyJump) {
                            if (!m_toastShown) {
                                // 页面加载是常态，减少干扰提示
                                m_toastShown = true;
                                QTimer::singleShot(TOAST_SHORT_MS, this, [this]() { m_toastShown = false; });
                            }
                            return;
                        }
                        // 使用统一的方法处理页面跳转和高亮
                        if (m_currentMode != LayoutMode::SingleColumn) {
                            int totalThumbnails = m_virtualThumbnailView ? m_virtualThumbnailView->count() : 0;
                            int columnMode = static_cast<int>(m_currentMode);
                            HighlightGuard guard(m_skipClearHighlightOnce);
                            m_pageView->setCurrentPageWithHighlight(targetCompositeIndex, index, totalThumbnails, columnMode);
                        } else {
                            // 单栏模式直接跳转到原始页面
                            HighlightGuard guard(m_skipClearHighlightOnce);
                            m_pageView->setCurrentPage(originalPageIndex);
                        }
                    } else {
                    }
                });
            } else {
                // **防护机制**: 即使没有完全加载，也尝试跳转，但要验证目标页面
                auto layoutGuard = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                int targetCompositeIndex = compositePageIndex;
                // **新增**: 验证目标页面是否可用
                bool canAttemptJump = false;
                if (targetCompositeIndex < layoutGuard.pages.size()) {
                    const QImage& targetImage = layoutGuard.pages[targetCompositeIndex];
                    if (!NextGenPlaceholder::isPlaceholder(targetImage)) {
                        canAttemptJump = true;
                    } else {
                    }
                }
                if (canAttemptJump) {
                    QTimer::singleShot(NAVIGATE_DELAY_MS, this, [this, targetCompositeIndex, index]() {
                        if (m_pageView && targetCompositeIndex >= 0 && targetCompositeIndex < m_pageView->pageCount()) {
                            if (m_currentMode != LayoutMode::SingleColumn) {
                                int totalThumbnails = m_virtualThumbnailView ? m_virtualThumbnailView->count() : 0;
                                int columnMode = static_cast<int>(m_currentMode);
                                m_pageView->setCurrentPageWithHighlight(targetCompositeIndex, index, totalThumbnails, columnMode);
                            }
                        }
                    });
                } else {
                    // **防护提示**: 无法跳转时给用户提示
                    if (!m_toastShown) {
                        // 页面处理是常态，减少干扰提示
                        m_toastShown = true;
                        QTimer::singleShot(4000, this, [this]() { m_toastShown = false; });
                    }
                }
            }
        }
    }
}
// 已删除：loadPagesFromCacheOrGenerate - 现在使用统一的缓存加载
void MainWindow::updateViewsWithPages(const QList<QImage>& pages)
{
    if (pages.isEmpty()) {
        return;
    }
    // 更新虚拟滚动缩略图视图
    try {
        // 显示所有缩略图，不再限制页数
        if (m_virtualThumbnailView) {
            m_virtualThumbnailView->setThumbnails(pages);
        }
    } catch (const std::exception& e) {
        return;
    } catch (...) {
        return;
    }
    // 更新页面视图 - 使用滚动位置保护方法
    try {
        if (m_isFileProcessing) {
            // 文件处理中，使用保护方法避免滚动位置重置
            m_pageView->setPagesPreservingScroll(pages);
        } else {
            // 正常情况，使用标准方法
            m_pageView->setPages(pages);
        }
    } catch (const std::exception& e) {
        return;
    } catch (...) {
        return;
    }
    // 设置当前页面 - 根据处理状态决定是否重置
    if (!m_isFileProcessing) {
        // 非处理状态，正常设置页面
        m_pageView->setCurrentPage(0);
        // Martin Fowler重构：移除重复的fitHeight调用，PageView会自动应用智能缩放
    } else {
        // 处理中状态，不重置页面和缩放
    }
}
void MainWindow::updateViewsWithPagesAndThumbnails(const QList<QImage>& pages, const QList<QImage>& thumbnails)
{
    // **已弃用**: 这个方法现在在loadFileFromCache中直接处理
}
// 已删除：generatePage - 现在使用统一的缓存加载
// 已删除：generatePDFPage - 现在使用统一的缓存加载
// 已删除：generateImagePage - 现在使用统一的缓存加载
int MainWindow::calculateImagePageCount(const QImage& image, LayoutMode mode)
{
    return m_imageProcessor->calculateImagePageCount(image, mode);
}
void MainWindow::precalculateImageSplitPositions(const QImage& image)
{
    try {
        m_imageSplitPositions = m_imageProcessor->calculateSplitPositions(image);
        // 输出前几个分割位置用于调试
        for (int i = 0; i < qMin(5, m_imageSplitPositions.size()); ++i) {
        }
    } catch (const std::exception& e) {
    } catch (...) {
    }
}
QList<QImage> MainWindow::generateImageSlicesFromPositions(const QImage& image, int startSliceIndex, int sliceCount)
{
    if (image.isNull() || sliceCount <= 0 || m_imageSplitPositions.isEmpty()) {
        return QList<QImage>();
    }
    try {
        // 使用预计算的分割位置生成切片
        QList<QImage> slices = m_imageProcessor->generateSlicesAtPositions(image, m_imageSplitPositions, startSliceIndex, sliceCount);
        return slices;
    } catch (const std::exception& e) {
        return QList<QImage>();
    } catch (...) {
        return QList<QImage>();
    }
}
double MainWindow::calculateOptimalDPI(int pageCount, qint64 fileSize) const
{
    // 智能DPI计算 - 使用系统配置的处理质量DPI（用于缓存分页处理）
    double baseDPI = getProcessingDpi();
    // // 根据页面数量调整 - 页面越多，DPI越低
    // if (pageCount > 500) {
    //     baseDPI = 120.0;  // 超大文档使用中等DPI
    // } else if (pageCount > 200) {
    //     baseDPI = 150.0;  // 大文档使用高DPI
    // } else if (pageCount > 100) {
    //     baseDPI = 180.0;  // 中等文档使用更高DPI
    // } else if (pageCount > 50) {
    //     baseDPI = 200.0;  // 小文档使用最高DPI
    // } else {
    //     baseDPI = 200.0;  // 极小文档使用最高DPI
    // }
    // // 根据文件大小进一步调整 (如果提供了文件大小)
    // if (fileSize > 0) {
    //     qint64 fileSizeMB = fileSize / (1024 * 1024);
    //     if (fileSizeMB > 100) {
    //         baseDPI = qMin(baseDPI, 120.0);  // 大文件降低DPI，但不要太低
    //     } else if (fileSizeMB > 50) {
    //         baseDPI = qMin(baseDPI, 150.0);  // 中等文件稍微降低DPI
    //     }
    // }
    return baseDPI;
}
QList<QImage> MainWindow::loadPagesLazy(const QString& fileIdentity, int totalPages)
{
    QList<QImage> pages;
    int preloadCount = qMin(getPreloadRange(), totalPages);
    // 获取缓存目录
    QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
    QString cacheDir = m_cacheManager->getCacheDirectory() + "/" + cacheKey;
    // 只预加载前几页，其余创建占位符
    for (int i = 0; i < totalPages; ++i) {
        if (i < preloadCount) {
            // TDD: 使用统一缓存服务预加载前几页（第3处消除）
            QImage unifiedPage = loadPageFromUnifiedCache(i);
            if (!unifiedPage.isNull()) {
                pages.append(unifiedPage);
            } else {
                pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中..."));
            }
        } else {
            // 其余页面创建加载占位符，后续按需加载
            pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "加载中..."));
        }
        // 每处理10页就处理一次事件，保持UI响应
        if (i % 10 == 0) {
            QApplication::processEvents();
        }
    }
    return pages;
}
QList<QImage> MainWindow::loadThumbnailsFromCache(const QString& fileIdentity, int totalPages)
{
    QList<QImage> thumbnails;
    // 获取缓存目录
    QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
    QString cacheDir = m_cacheManager->getCacheDirectory() + "/" + cacheKey;
    QDir dir(cacheDir);
    if (!dir.exists()) {
        return thumbnails;
    }
    // 查找缩略图目录
    QString thumbnailDir = cacheDir + "/thumbnails";
    QDir thumbDir(thumbnailDir);
    if (!thumbDir.exists()) {
        return thumbnails;
    }
    // 列出缩略图目录中的所有文件
    QStringList files = thumbDir.entryList(QStringList() << "thumb_*.png", QDir::Files);
    // 加载所有缩略图
    for (int i = 0; i < totalPages; ++i) {
        QString fileName = QString("thumb_%1.png").arg(i, 5, 10, QChar('0'));
        QString filePath = thumbnailDir + "/" + fileName;
        if (QFile::exists(filePath)) {
            QImage thumbnail(filePath);
            if (!thumbnail.isNull()) {
                thumbnails.append(thumbnail);
            } else {
                // 如果缩略图加载失败，创建占位符
                thumbnails.append(NextGenPlaceholder::createLoading(QSize(200, 300), "加载中..."));
            }
        } else {
            // 如果缩略图不存在，创建占位符
            thumbnails.append(NextGenPlaceholder::createLoading(QSize(200, 300), "加载中..."));
        }
    }
    return thumbnails;
}
QList<QImage> MainWindow::createLayoutPlaceholders(LayoutMode layoutMode) const
{
    QList<QImage> placeholders;
    // 根据布局模式确定占位符数量
    int placeholderCount = 1; // 默认单栏
    switch (layoutMode) {
        case LayoutMode::SingleColumn:
            placeholderCount = 1;
            break;
        case LayoutMode::TwoColumns:
            placeholderCount = 4; // 2x2
            break;
        case LayoutMode::ThreeColumns:
            placeholderCount = 9; // 3x3
            break;
    }
    for (int i = 0; i < placeholderCount; ++i) {
        QImage placeholder(400, 600, QImage::Format_RGB32);
        placeholder.fill(QColor(248, 248, 248));
        QPainter painter(&placeholder);
        painter.setRenderHint(QPainter::Antialiasing);
        // 绘制边框
        painter.setPen(QPen(QColor(200, 200, 200), 2));
        painter.drawRect(placeholder.rect().adjusted(10, 10, -10, -10));
        // 绘制占位符图标 (简单的几何图形)
        painter.setPen(QPen(QColor(150, 150, 150), 3));
        int centerX = placeholder.width() / 2;
        int centerY = placeholder.height() / 2;
        // 绘制同心圆
        for (int radius = 20; radius <= 60; radius += 20) {
            painter.drawEllipse(centerX - radius, centerY - radius, radius * 2, radius * 2);
        }
        // 绘制对角线
        painter.drawLine(centerX - 50, centerY - 50, centerX + 50, centerY + 50);
        painter.drawLine(centerX + 50, centerY - 50, centerX - 50, centerY + 50);
        // 绘制文本
        painter.setPen(QColor(120, 120, 120));
        painter.setFont(QFont("Arial", 14, QFont::Bold));
        QString text = QString("占位符 %1\n\n文件处理中...").arg(i + 1);
        painter.drawText(placeholder.rect(), Qt::AlignCenter, text);
        placeholders.append(placeholder);
    }
    return placeholders;
}
void MainWindow::updateThumbnailsRealtime(const QString& fileIdentity, int progress)
{
    // 设置文件处理状态
    m_isFileProcessing = true;
    emit fileProcessingStateChanged(true);
    // 设置PageView为处理模式，避免滚动位置重置
    if (m_pageView) {
        m_pageView->setProcessingMode(true);
    }
    // 保存当前主图滚动位置（调试信息）
    if (m_pageView) {
        QScrollBar* vScrollBar = m_pageView->verticalScrollBar();
        QScrollBar* hScrollBar = m_pageView->horizontalScrollBar();
        int currentPage = m_pageView->currentPage();
    }
    // 获取缓存目录
    QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
    QString cacheDir = m_cacheManager->getCacheDirectory() + "/" + cacheKey;
    QDir dir(cacheDir);
    if (!dir.exists()) {
        return;
    }
    // 获取当前已处理的页面数量
    QStringList pageFiles = dir.entryList(QStringList() << "page_*.png", QDir::Files);
    int processedPages = pageFiles.size();
    // **关键修复**: 只更新缩略图，不重新设置主图页面
    if (m_virtualThumbnailView && processedPages > 0) {
        // 如果当前缩略图视图的页数少于已处理页数，需要扩展
        if (m_virtualThumbnailView->count() < processedPages) {
            m_virtualThumbnailView->setThumbnailsFromCache(fileIdentity, processedPages);
        }
        // 只刷新缩略图，不重新设置主图页面
        m_virtualThumbnailView->refreshThumbnailsFromCache(fileIdentity);
    }
    // 检查更新后的主图滚动位置（调试信息）
    if (m_pageView) {
        QScrollBar* vScrollBar = m_pageView->verticalScrollBar();
        QScrollBar* hScrollBar = m_pageView->horizontalScrollBar();
        int currentPage = m_pageView->currentPage();
    }
}
// 防抖超时处理方法已移除，使用智能刷新机制
void MainWindow::managePagesMemory(int currentPageIndex)
{
    if (m_pages.size() <= getMaxPagesInMemory()) {
        return; // 页面数量未超过限制
    }
    // 跟踪访问过的页面范围，避免频繁清理最近访问的页面
    static int lastMinAccessed = 0;
    static int lastMaxAccessed = 0;
    // 更新访问范围
    if (lastMinAccessed == 0 && lastMaxAccessed == 0) {
        // 首次初始化
        lastMinAccessed = currentPageIndex;
        lastMaxAccessed = currentPageIndex;
    } else {
        lastMinAccessed = qMin(lastMinAccessed, currentPageIndex);
        lastMaxAccessed = qMax(lastMaxAccessed, currentPageIndex);
    }
    // 计算保留范围：在访问范围基础上再扩展动态KEEP_RANGE
    int keepRange = getKeepRange();
    int startKeep = qMax(0, qMin(currentPageIndex - keepRange, lastMinAccessed - 10));
    int endKeep = qMin(m_pages.size() - 1, qMax(currentPageIndex + keepRange, lastMaxAccessed + 10));
    // 将超出范围的页面替换为占位符
    for (int i = 0; i < m_pages.size(); ++i) {
        if (i < startKeep || i > endKeep) {
            // 超出保留范围，需要清理
            if (NextGenPlaceholder::isRealContent(m_pages[i])) {
                // 如果是大图，替换为占位符
                m_pages[i] = NextGenPlaceholder::createCacheMissing(QSize(800, 1200), "已清理");
            }
        }
    }
}
void MainWindow::preloadNearbyPages(int currentPage)
{
    // **重构**: 使用智能预加载调度器
    smartPreloadPages(currentPage);
}
void MainWindow::smartPreloadPages(int currentPage)
{
    // **新增**: 滚动方向预测和智能预加载
    static int lastPage = -1;
    static int scrollDirection = 0; // -1向前，0无方向，1向后
    static QElapsedTimer scrollTimer;
    static int consecutiveDirection = 0;
    if (lastPage != -1 && currentPage != lastPage) {
        int newDirection = (currentPage > lastPage) ? 1 : -1;
        // 检测连续滚动方向
        if (newDirection == scrollDirection) {
            consecutiveDirection++;
        } else {
            scrollDirection = newDirection;
            consecutiveDirection = 1;
            scrollTimer.start();
        }
        // **智能预测**: 连续同方向滚动时，增强该方向的预加载
        if (consecutiveDirection >= 2) {
            int predictiveRange = qMin(8, consecutiveDirection * 2); // 最多预加载8页
            // 在滚动方向上预加载更多页面
            for (int i = 1; i <= predictiveRange; ++i) {
                int predictivePage = currentPage + (scrollDirection * i);
                if (predictivePage >= 0 && predictivePage < m_pages.size()) {
                    const QImage& page = m_pages[predictivePage];
                    if (NextGenPlaceholder::isPlaceholder(page)) {
                        loadPageAsync(predictivePage);
                    }
                } else if (predictivePage >= m_pages.size() && predictivePage < m_pdfPageCount) {
                    // 需要扩展并加载新页面
                    while (m_pages.size() <= predictivePage) {
                        m_pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "预测加载中..."));
                    }
                    loadPageAsync(predictivePage);
                }
            }
        }
    }
    lastPage = currentPage;
    // **关键修复**: 首先确保当前页面已加载（同步加载）
    if (currentPage >= 0 && currentPage < m_pages.size()) {
        const QImage& currentPageImage = m_pages[currentPage];
        if (NextGenPlaceholder::isPlaceholder(currentPageImage)) {
            QImage loadedPage = loadPageFromUnifiedCache(currentPage);
            if (!loadedPage.isNull() && !NextGenPlaceholder::isPlaceholder(loadedPage)) {
                m_pages[currentPage] = loadedPage;
                // **增强修复**: 立即更新视图并确保视图不被后续操作覆盖
                auto layoutUrgent = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
                m_pageView->updatePagesWithoutReset(layoutUrgent.pages);
                if (m_currentMode != LayoutMode::SingleColumn) {
                    m_pageView->setAccurateLayoutRects(layoutUrgent.layoutRects);
                }
                // **新增**: 确保UI立即反映变化，避免异步更新覆盖
            } else {
                // **新增**: 缓存加载失败时的降级处理
                if (!loadedPage.isNull()) {
                    QString placeholderInfo = NextGenPlaceholder::getPlaceholderInfo(loadedPage);
                }
            }
        } else {
            // **新增**: 即使当前页面不是占位符，也进行一次验证
        }
    } else if (currentPage >= 0) {
        // **新增**: 当前页面索引超出范围的处理
        // 扩展页面数组
        while (m_pages.size() <= currentPage) {
            m_pages.append(NextGenPlaceholder::createLoading(QSize(800, 1200), "扩展加载中..."));
        }
        // 从缓存加载当前页面
        QImage loadedPage = loadPageFromUnifiedCache(currentPage);
        if (!loadedPage.isNull() && !NextGenPlaceholder::isPlaceholder(loadedPage)) {
            m_pages[currentPage] = loadedPage;
            // 立即更新视图
            auto layoutUrgent2 = m_unifiedRenderer->rearrangeWithLayout(m_pages, m_currentMode);
            m_pageView->updatePagesWithoutReset(layoutUrgent2.pages);
            if (m_currentMode != LayoutMode::SingleColumn) {
                m_pageView->setAccurateLayoutRects(layoutUrgent2.layoutRects);
            }
        }
    }
    // **第一层**: 立即预加载（高优先级，当前页±2页）
    int immediateRange = 2;
    for (int i = currentPage - immediateRange; i <= currentPage + immediateRange; ++i) {
        if (i >= 0 && i < m_pages.size() && i != currentPage) {  // 跳过当前页（已处理）
            const QImage& page = m_pages[i];
            if (NextGenPlaceholder::isPlaceholder(page)) {
                loadPageAsync(i);
            }
        }
    }
    // **第二层**: 组合页面优化预加载（针对多栏布局）
    if (m_currentMode != LayoutMode::SingleColumn) {
        preloadForCompositeMode(currentPage, m_currentMode);
    }
    // **第三层**: 后台预加载（延迟执行，避免阻塞用户交互）
    QTimer::singleShot(TOAST_MEDIUM_MS, this, [this, currentPage]() {
        backgroundPreload(currentPage);
    });
    // **第四层**: 空闲时预加载（进一步延迟）
    QTimer::singleShot(TOAST_LONG_MS, this, [this]() {
        idlePreload();
    });
}
void MainWindow::backgroundPreload(int currentPage)
{
    // **智能范围**: 根据滚动模式调整预加载范围
    static int lastDirection = 0;
    static int enhancedRange = 8;
    // 获取当前滚动方向信息
    static int lastBackgroundPage = -1;
    if (lastBackgroundPage != -1) {
        int currentDirection = (currentPage > lastBackgroundPage) ? 1 : (currentPage < lastBackgroundPage) ? -1 : 0;
        if (currentDirection == lastDirection && currentDirection != 0) {
            enhancedRange = qMin(12, enhancedRange + 1); // 逐渐增加预加载范围
        } else {
            enhancedRange = qMax(6, enhancedRange - 1); // 逐渐减少预加载范围
        }
        lastDirection = currentDirection;
    }
    lastBackgroundPage = currentPage;
    // **优先级预加载**: 按距离排序，近的先加载
    QList<int> preloadOrder;
    for (int i = currentPage - enhancedRange; i <= currentPage + enhancedRange; ++i) {
        if (i >= 0 && i < m_pages.size() && i != currentPage) {
            preloadOrder.append(i);
        }
    }
    // 按距离当前页面的远近排序
    std::sort(preloadOrder.begin(), preloadOrder.end(), [currentPage](int a, int b) {
        return qAbs(a - currentPage) < qAbs(b - currentPage);
    });
    // 分批加载，避免阻塞
    int loadedCount = 0;
    const int maxBatchLoad = 6; // 每批最多加载6页
    for (int pageIndex : preloadOrder) {
        if (loadedCount >= maxBatchLoad) break;
        const QImage& page = m_pages[pageIndex];
        if (NextGenPlaceholder::isPlaceholder(page)) {
            loadPageAsync(pageIndex);
            loadedCount++;
            // 每加载2页就处理一次事件，保持UI响应性
            if (loadedCount % 2 == 0) {
                QApplication::processEvents();
            }
        }
    }
}
void MainWindow::idlePreload()
{
    if (m_isFileProcessing) {
        return;
    }
    // 检查所有页面，预加载任何未加载的页面（优先加载靠前的页面）
    int loadedCount = 0;
    const int maxIdleLoad = 20; // 一次空闲预加载最多20页
    for (int i = 0; i < m_pages.size() && loadedCount < maxIdleLoad; ++i) {
        const QImage& page = m_pages[i];
        if (NextGenPlaceholder::isPlaceholder(page)) {
            loadPageAsync(i);
            loadedCount++;
            // 每加载5页就处理一次事件并稍作休息
            if (loadedCount % 5 == 0) {
                QApplication::processEvents();
                QThread::msleep(50); // 休息50ms，避免占用太多CPU
            }
        }
    }
}
void MainWindow::preloadForCompositeMode(int currentPage, LayoutMode mode)
{
    int pagesPerComposite = m_unifiedRenderer->pagesPerComposite(m_currentMode);
    // 计算当前组合页面索引
    int currentComposite = currentPage / pagesPerComposite;
    // **关键优化**: 预加载前后2个完整组合页面
    int preloadComposites = 2;
    for (int comp = currentComposite - preloadComposites; comp <= currentComposite + preloadComposites; comp++) {
        if (comp < 0) continue;
        // 计算该组合页面包含的原始页面范围
        int compositeStartPage = comp * pagesPerComposite;
        int compositeEndPage = qMin(compositeStartPage + pagesPerComposite, m_pages.size());
        // 预加载该组合页面的所有原始页面
        for (int i = compositeStartPage; i < compositeEndPage; ++i) {
            if (i >= 0 && i < m_pages.size()) {
                const QImage& page = m_pages[i];
                if (NextGenPlaceholder::isPlaceholder(page)) {
                    loadPageAsync(i);
                }
            }
        }
    }
}
void MainWindow::loadPageAsync(int pageIndex)
{
    if (pageIndex < 0 || pageIndex >= m_pages.size()) return;
    if (!m_pages[pageIndex].isNull()) return; // 已经加载过了
    // TDD: 使用统一缓存服务替换重复代码
    QImage unifiedPage = loadPageFromUnifiedCache(pageIndex);
    if (!unifiedPage.isNull()) {
        m_pages[pageIndex] = unifiedPage;
        return;
    }
    // 如果统一缓存服务也没有，显示占位符
}
void MainWindow::toggleLeftSidebar()
{
    if (!m_fileBrowserDock) {
        return; // 如果dock widget还没有创建，直接返回
    }

    if (m_fileBrowserDock->isVisible()) {
        m_fileBrowserDock->hide();
        if (m_toggleLeftSidebarAction) {
            m_toggleLeftSidebarAction->setChecked(false);
        }
    } else {
        m_fileBrowserDock->show();
        if (m_toggleLeftSidebarAction) {
            m_toggleLeftSidebarAction->setChecked(true);
        }

        // 手动切换显示时，也应用保存的宽度
        if (m_savedFileBrowserWidth > 0) {
            QTimer::singleShot(50, this, [this]() {
                if (m_fileBrowserDock && m_fileBrowserDock->isVisible() && m_savedFileBrowserWidth > 0) {
                    QList<QDockWidget*> docks = {m_fileBrowserDock};
                    QList<int> sizes = {m_savedFileBrowserWidth};
                    resizeDocks(docks, sizes, Qt::Horizontal);
                }
            });
        }
    }
}
void MainWindow::toggleRightSidebar()
{
    if (!m_thumbnailDock) {
        return; // 如果dock widget还没有创建，直接返回
    }

    if (m_thumbnailDock->isVisible()) {
        m_thumbnailDock->hide();
        if (m_toggleRightSidebarAction) {
            m_toggleRightSidebarAction->setChecked(false);
        }
    } else {
        m_thumbnailDock->show();
        if (m_toggleRightSidebarAction) {
            m_toggleRightSidebarAction->setChecked(true);
        }

        // 不再恢复保存的宽度，使用默认宽度
    }
}
// updateSidebarVisibility 函数已删除 - 不再管理停靠窗口状态
void MainWindow::onLayoutModeRequested(int layoutMode)
{
    // 不再自动应用布局模式，让文件加载时从统一状态管理器获取
    // 注释掉自动布局模式切换逻辑
    /*
    // 转换为统一的布局模式枚举 - 直接映射LayoutStateManager的枚举值
    LayoutMode newMode = static_cast<LayoutMode>(layoutMode + 1);
    // 验证范围
    if (newMode < LayoutMode::SingleColumn || newMode > LayoutMode::ThreeColumns) {
        newMode = LayoutMode::SingleColumn;
    }
    // 使用QTimer延迟执行，确保文件加载完成后再应用布局
    QTimer::singleShot(LAYOUT_RECOMPUTE_DELAY_MS, [this, newMode]() {
        // 检查是否有当前文档
        if (m_pages.isEmpty()) {
            return;
        }
        switchColumnMode(newMode, true); // 标记为来自文件列表的请求
    });
    */
}
// 文件处理状态管理方法实现
void MainWindow::startFileProcessing()
{
    // 获取所有文件
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (files.isEmpty()) {
        return;
    }
    // 启用PageView的渐进式页面更新，并设置当前文件标识
    if (m_pageView && !files.isEmpty()) {
        // 获取当前选中文件的标识
        QString currentFileId = currentFileIdentity();
        if (!currentFileId.isEmpty()) {
            m_pageView->enableProgressivePageUpdate(true);
            m_pageView->refreshPagesFromCache(currentFileId);
        } else {
        }
    }
    // 为每个文件提交处理任务
    for (int i = 0; i < files.size(); ++i) {
        const UnifiedFileInfo& fileInfo = files[i];
        submitFileProcessingTask(i, fileInfo.filePath);
    }
}
void MainWindow::submitFileProcessingTask(int fileIndex, const QString& filePath)
{
    // 获取文件身份标识，用于安全的拖拽后进度更新
    QString fileIdentity = m_fileBrowser->getFileIdentityByIndex(fileIndex);
    if (fileIdentity.isEmpty()) {
        qWarning() << "无法获取文件身份标识，跳过任务提交:" << filePath;
        return;
    }

    // 创建文件处理任务 - 不需要传递缓存目录，FileProcessWorker会使用UnifiedCacheManager的默认缓存
    auto task = std::make_shared<FileProcessingTask>(filePath, "", fileIndex);
    // 建立任务ID到文件身份的映射（拖拽安全）
    m_taskToFileIdentity[task->getTaskId()] = fileIdentity;
    // 保持向后兼容的索引映射（临时）
    m_taskToFileIndex[task->getTaskId()] = fileIndex;

    // 直接连接任务的进度信号到MainWindow的进度更新方法
    connect(task.get(), &FileProcessingTask::progressUpdated, this, [this, fileIdentity](const QString& taskId, int progress, const QString& status) {
        // 使用文件身份更新进度（拖拽安全）
        if (m_fileBrowser) {
            m_fileBrowser->updateFileProgressByIdentity(fileIdentity, progress, status);
        }
        // 检查是否为当前显示的文件，如果是则实时更新缩略图（通过文件身份）
        if (m_fileBrowser && fileIdentity == m_currentFileHash) {
            // 保持懒加载原则，不主动更新缩略图
            // 缩略图将通过滚动触发的动态边界扩展来加载
        }
    });
    // 连接任务完成信号
    connect(task.get(), &FileProcessingTask::taskCompleted, this, [this, fileIdentity](const QString& taskId, bool success, const QString& errorMessage) {
        if (success) {
            // 使用文件身份设置完成状态（拖拽安全）
            if (m_fileBrowser) {
                m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Completed, 100, tr("已完成"));
                // 通过文件身份获取当前文件信息（拖拽安全）
                int currentFileIndex = m_fileBrowser->findIndexByFileIdentity(fileIdentity);
                if (currentFileIndex >= 0) {
                    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
                    if (currentFileIndex < files.size()) {
                        const UnifiedFileInfo& fileInfo = files[currentFileIndex];
                        // 从缓存管理器获取页数信息
                        UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
                        if (cacheManager) {
                            int pageCount = cacheManager->getCachedPageCount(fileInfo.filePath);
                            QDateTime latestTime = cacheManager->getCachedLatestTime(fileInfo.filePath);
                            if (pageCount > 0) {
                                m_fileBrowser->setProcessedMetadata(currentFileIndex, fileIdentity, pageCount, latestTime);
                            } else {
                            }
                        } else {
                        }
                    }
                }
            }
            // Martin Fowler Observer Pattern: 文件处理完成后异步应用智能布局（使用当前索引）
            int currentFileIndex = m_fileBrowser->findIndexByFileIdentity(fileIdentity);
            if (currentFileIndex >= 0) {
                applySmartLayoutAfterFileProcessing(currentFileIndex);
            }
        } else {
            // 使用文件身份设置错误状态（拖拽安全）
            if (m_fileBrowser) {
                m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Error, 0,
                                                     errorMessage.isEmpty() ? tr("处理失败") : errorMessage);
            }
        }
        // 移除任务映射
        m_taskToFileIndex.remove(taskId);
        m_taskToFileIdentity.remove(taskId);
    });
    // 设置文件状态为处理中（使用文件身份，排序安全）
    m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Processing, 0, "等待处理");

    // 提交任务到统一线程管理器
    bool submitted = UnifiedThreadManager::instance()->submitTask(task);
    if (submitted) {
    } else {
        // 提交失败时，使用文件身份设置错误状态（拖拽安全）
        if (m_fileBrowser) {
            m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Error, 0, "任务提交失败");
        }
        // 移除任务映射
        m_taskToFileIndex.remove(task->getTaskId());
        m_taskToFileIdentity.remove(task->getTaskId());
    }
}
void MainWindow::updateProcessingStatus()
{
    if (!m_fileBrowser) return;
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (files.isEmpty()) return;
    int totalFiles = files.size();
    int completedFiles = 0;
    int processingFiles = 0;
    int errorFiles = 0;
    int queuedFiles = 0;
    for (int i = 0; i < files.size(); ++i) {
        const UnifiedFileInfo& file = files[i];
        int statusValue = static_cast<int>(file.processStatus);
        switch (file.processStatus) {
            case FileProcessStatus::Completed:
                completedFiles++;
                break;
            case FileProcessStatus::Processing:
                processingFiles++;
                break;
            case FileProcessStatus::Error:
                errorFiles++;
                break;
            case FileProcessStatus::Waiting:
                queuedFiles++;
                break;
        }
    }
    QString statusText = QString("文件处理状态: 总计 %1, 完成 %2, 处理中 %3, 错误 %4, 等待 %5")
                        .arg(totalFiles).arg(completedFiles).arg(processingFiles).arg(errorFiles).arg(queuedFiles);
    // 更新状态栏
    statusBar()->showMessage(statusText, 5000);
}
// Martin Fowler Observer Pattern: 异步智能布局判断
void MainWindow::applySmartLayoutAfterFileProcessing(int fileIndex)
{
    if (!m_fileBrowser) {
        return;
    }
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (fileIndex < 0 || fileIndex >= files.size()) {
        return;
    }
    const UnifiedFileInfo& fileInfo = files[fileIndex];
    QString filePath = fileInfo.filePath;
    // 获取推荐的布局模式
    LayoutMode recommendedLayout;
    // 使用配置驱动的布局决策，统一通过getDefaultLayoutModeWithConfig处理
    QImageReader reader(filePath);
    QSize imageSize;
    if (reader.canRead() && reader.size().isValid()) {
        imageSize = reader.size();
    }
    recommendedLayout = LayoutStateManager::getDefaultLayoutModeWithConfig(
        filePath, m_systemConfig, imageSize.width(), imageSize.height());
    // Martin Fowler Strategy Pattern: 区分当前文件和其他文件的处理策略
    QString currentFileIdentity = m_currentFileHash;
    QString processFileIdentity = FileIdentityManager::getFileIdentity(filePath);
    bool isCurrentFile = (currentFileIdentity == processFileIdentity);
    if (isCurrentFile) {
        // 策略1: 当前显示的文件 - 只在首次加载时应用智能布局
        // 修复：避免在页面重绘时重新计算布局模式，保持用户当前选择的布局
        LayoutMode currentLayoutMode = LayoutStateManager::instance()->getCurrentLayoutMode();
        if (currentLayoutMode == LayoutMode::SingleColumn && recommendedLayout != LayoutMode::SingleColumn) {
            // 只有在当前是默认单栏模式且推荐其他模式时，才应用智能布局
            // 这表示文件是首次加载，还没有用户自定义的布局选择
            switchColumnMode(recommendedLayout);
            // 显示布局切换提示
            QString layoutText = LayoutStateManager::getLayoutModeText(recommendedLayout);
            // 布局变更通过UI视觉反馈即可，无需toast提示
        } else {
        }
    } else {
        // 策略2: 其他文件 - 只在文件浏览器中标注布局模式
        if (m_fileBrowser) {
            m_fileBrowser->setFileLayoutMode(fileIndex, recommendedLayout);
        }
    }
}
// IProgressObserver接口实现
void MainWindow::onProgressUpdated(const QString& taskId, int progress, const QString& status)
{
    // 优先使用文件身份映射（拖拽安全）
    if (m_taskToFileIdentity.contains(taskId)) {
        QString fileIdentity = m_taskToFileIdentity[taskId];
        // 使用文件身份更新进度（拖拽安全）
        if (m_fileBrowser) {
            m_fileBrowser->updateFileProgressByIdentity(fileIdentity, progress, status);
        }
        // 通知PageView进度更新，触发渐进式页面更新
        if (m_pageView && progress > 0) {
            // 通过文件身份获取当前文件信息
            int currentFileIndex = m_fileBrowser->findIndexByFileIdentity(fileIdentity);
            if (currentFileIndex >= 0) {
                QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
                if (currentFileIndex < files.size()) {
                    const UnifiedFileInfo& fileInfo = files[currentFileIndex];
                    int totalPages = fileInfo.pageCount > 0 ? fileInfo.pageCount : 1;
                    int completedPages = (progress * totalPages) / 100;
                    // 只在当前显示的文件时通知PageView
                    if (fileInfo.fileIdentity == m_currentFileHash) {
                        m_pageView->updateProcessingProgress(completedPages, totalPages);
                    }
                }
            }
        }
    } else if (m_taskToFileIndex.contains(taskId)) {
        // 回退到索引映射（兼容性）
        int fileIndex = m_taskToFileIndex[taskId];
        if (m_fileBrowser) {
            m_fileBrowser->updateFileProgress(fileIndex, progress, status);
        }
    } else {
    }
}
void MainWindow::onTaskCompleted(const QString& taskId)
{
    // 优先使用文件身份映射（拖拽安全）
    if (m_taskToFileIdentity.contains(taskId)) {
        QString fileIdentity = m_taskToFileIdentity[taskId];
        // 使用文件身份设置完成状态（拖拽安全）
        if (m_fileBrowser) {
            m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Completed, 100, tr("已完成"));
            // 通知设置面板页数可能已更新
            if (m_settingsWidget) {
                m_settingsWidget->onPageCountChanged();
            }
            // 通过文件身份获取当前文件信息并更新页数（拖拽安全）
            int currentFileIndex = m_fileBrowser->findIndexByFileIdentity(fileIdentity);
            if (currentFileIndex >= 0) {
                QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
                if (currentFileIndex < files.size()) {
                    const UnifiedFileInfo& fileInfo = files[currentFileIndex];
                    // 从缓存管理器获取页数信息
                    UnifiedCacheManager* cacheManager = UnifiedCacheManager::instance();
                    if (cacheManager) {
                        int pageCount = cacheManager->getCachedPageCount(fileInfo.filePath);
                        QDateTime latestTime = cacheManager->getCachedLatestTime(fileInfo.filePath);
                        if (pageCount > 0) {
                            m_fileBrowser->setProcessedMetadata(currentFileIndex, fileIdentity, pageCount, latestTime);
                        // 检查是否为当前显示的文件，如果是则禁用渐进式加载
                        if (fileIdentity == m_currentFileHash) {
                            // 禁用缩略图渐进式加载
                            if (m_virtualThumbnailView) {
                                m_virtualThumbnailView->enableProgressiveLoading(false);
                                // 最后一次刷新缩略图以确保所有缩略图都已加载
                                m_virtualThumbnailView->refreshThumbnailsFromCache(fileIdentity);
                            }
                            // 禁用页面渐进式更新
                            if (m_pageView) {
                                m_pageView->enableProgressivePageUpdate(false);
                                // 最后一次刷新页面以确保所有页面都已加载
                                m_pageView->refreshPagesFromCache(fileIdentity);
                            }
                            // 文件处理完成，重置处理状态
                            m_isFileProcessing = false;
                            emit fileProcessingStateChanged(false);
                            m_savedCurrentPage = -1;
                            m_savedScrollOffset = QPoint();
                            // 重置PageView处理模式
                            if (m_pageView) {
                                m_pageView->setProcessingMode(false);
                            }
                        }
                    } else {
                    }
                } else {
                }
                    }
                }
            }
        // 移除任务映射
        m_taskToFileIdentity.remove(taskId);
        // 更新处理状态
        updateProcessingStatus();
        // Martin Fowler Observer Pattern: 文件处理完成后异步应用智能布局（使用当前索引）
        int currentFileIndex = m_fileBrowser->findIndexByFileIdentity(fileIdentity);
        if (currentFileIndex >= 0) {
            applySmartLayoutAfterFileProcessing(currentFileIndex);
        }
    } else if (m_taskToFileIndex.contains(taskId)) {
        // 回退到索引映射（兼容性）
        int fileIndex = m_taskToFileIndex[taskId];
        if (m_fileBrowser) {
            m_fileBrowser->setFileCompleted(fileIndex);
        }
        // 移除任务映射
        m_taskToFileIndex.remove(taskId);
        // 更新处理状态
        updateProcessingStatus();
        // 应用智能布局
        applySmartLayoutAfterFileProcessing(fileIndex);
    } else {
    }
}
void MainWindow::onTaskFailed(const QString& taskId, const QString& error)
{
    // 优先使用文件身份映射（拖拽安全）
    if (m_taskToFileIdentity.contains(taskId)) {
        QString fileIdentity = m_taskToFileIdentity[taskId];
        // 使用文件身份设置错误状态（拖拽安全）
        if (m_fileBrowser) {
            m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Error, 0,
                                                 error.isEmpty() ? tr("处理失败") : error);
        }
        // 移除任务映射
        m_taskToFileIdentity.remove(taskId);
    } else if (m_taskToFileIndex.contains(taskId)) {
        // 回退到索引映射（兼容性）
        int fileIndex = m_taskToFileIndex[taskId];
        if (m_fileBrowser) {
            m_fileBrowser->setFileError(fileIndex, error);
        }
        // 移除任务映射
        m_taskToFileIndex.remove(taskId);
        // 显示错误提示
        showToastMessage(QString("处理失败: %1").arg(error));
        // 更新处理状态
        updateProcessingStatus();
    } else {
    }
}
void MainWindow::onTaskStarted(const QString& taskId)
{
}
void MainWindow::onTaskCancelled(const QString& taskId)
{
    // 查找任务对应的文件索引
    if (m_taskToFileIndex.contains(taskId)) {
        int fileIndex = m_taskToFileIndex[taskId];
        // 重置文件状态为队列状态（使用文件身份，排序安全）
        if (m_fileBrowser) {
            QString fileIdentity = m_fileBrowser->getFileIdentityByIndex(fileIndex);
            if (!fileIdentity.isEmpty()) {
                m_fileBrowser->setFileStatusByIdentity(fileIdentity, FileStatusIconManager::FileStatus::Queued, 0, "等待处理");
            }
        }
        // 移除任务映射
        m_taskToFileIndex.remove(taskId);
        // 显示取消提示
        // 任务取消是用户主动操作，无需toast提示
        // 更新处理状态
        updateProcessingStatus();
    } else {
    }
}
// TDD: 统一内存管理系统实现
void MainWindow::setupUnifiedMemoryManagement()
{
    // 使用MinimalUnifiedMemoryManager
    m_unifiedMemoryManager = std::make_unique<MinimalUnifiedMemoryManager>(this);
    // 配置内存池
    m_unifiedMemoryManager->registerPool(
        IUnifiedMemoryManager::ContentType::MAIN_PAGE, 
        690ULL * 1024 * 1024);  // 690MB主图缓存
    m_unifiedMemoryManager->registerPool(
        IUnifiedMemoryManager::ContentType::THUMBNAIL, 
        180ULL * 1024 * 1024);  // 180MB缩略图缓存
    m_unifiedMemoryManager->registerPool(
        IUnifiedMemoryManager::ContentType::COMPOSED_PAGE, 
        200ULL * 1024 * 1024);  // 200MB组合页缓存
    // 为VirtualThumbnailView设置统一内存管理器引用
    if (m_virtualThumbnailView) {
        // 直接调用方法设置统一内存管理器指针
        m_virtualThumbnailView->setUnifiedMemoryManager(m_unifiedMemoryManager.get());
    }
}
QImage MainWindow::loadPageFromUnifiedCache(int pageIndex)
{
    if (!m_unifiedMemoryManager) {
        return QImage();  // 回退机制
    }
    // PROFILE_MEMORY_OPERATION(nullptr, "unified_cache_load");  // TDD: 暂时注释掉
    // 使用统一内存管理器加载页面
    QImage image = m_unifiedMemoryManager->getImage(
        IUnifiedMemoryManager::ContentType::MAIN_PAGE, 
        pageIndex, 
        m_pageView ? m_pageView->currentPage() : -1);
    return image;
}
// 滚动位置管理实现
void MainWindow::saveScrollPosition()
{
    if (m_pageView && m_isFileProcessing) {
        m_savedCurrentPage = m_pageView->currentPage();
        // 获取滚动条位置
        QScrollBar* vScrollBar = m_pageView->verticalScrollBar();
        QScrollBar* hScrollBar = m_pageView->horizontalScrollBar();
        m_savedScrollOffset = QPoint(hScrollBar ? hScrollBar->value() : 0, 
                                    vScrollBar ? vScrollBar->value() : 0);
    }
}
void MainWindow::restoreScrollPosition()
{
    if (m_pageView && m_isFileProcessing && m_savedCurrentPage >= 0) {
        // 延迟恢复，确保视图已更新
        QTimer::singleShot(100, this, [this]() {
            if (m_pageView && m_savedCurrentPage >= 0 && m_savedCurrentPage < m_pages.size()) {
                // 恢复页面
                m_pageView->setCurrentPage(m_savedCurrentPage);
                // 恢复滚动位置
                QScrollBar* vScrollBar = m_pageView->verticalScrollBar();
                QScrollBar* hScrollBar = m_pageView->horizontalScrollBar();
                if (vScrollBar) {
                    vScrollBar->setValue(m_savedScrollOffset.y());
                }
                if (hScrollBar) {
                    hScrollBar->setValue(m_savedScrollOffset.x());
                }
            }
        });
    }
}
void MainWindow::onUnifiedImageLoaded(IUnifiedMemoryManager::ContentType type, int index, const QImage& image)
{
    switch (type) {
        case IUnifiedMemoryManager::ContentType::MAIN_PAGE:
            // 更新主图页面
            if (index >= 0 && index < m_pages.size()) {
                m_pages[index] = image;
                if (m_pageView && m_pageView->currentPage() == index) {
                    m_pageView->updatePageContent(index, image);
                }
            }
            break;
        case IUnifiedMemoryManager::ContentType::THUMBNAIL:
            // 更新缩略图
            if (m_virtualThumbnailView) {
                m_virtualThumbnailView->updateThumbnail(index, image);
            }
            break;
        case IUnifiedMemoryManager::ContentType::COMPOSED_PAGE:
            // 更新组合页面
            if (m_pageView) {
                m_pageView->updatePageContent(index, image);
            }
            break;
    }
}
// showPDFExportDialog方法已移除 - 使用状态条一键导出PDF替代
// 统一渲染器相关实现
void MainWindow::onProcessingSettingsChanged(const ProcessingSettings& settings)
{
    // 更新处理设置
    m_processingSettings = settings;
    // 更新统一渲染器设置
    if (m_unifiedRenderer) {
        m_unifiedRenderer->setRenderSettings(settings);
    }
    // 立即重新绘制当前页面（所见即所得）
    if (m_pageView) {
        m_pageView->forceUpdatePageNumbers();
    }
    // 更新状态条显示当前设置
    updateStatusBarSettings(settings);
}
void MainWindow::updateRenderSettings(const ProcessingSettings& settings)
{
    m_processingSettings = settings;
    if (m_unifiedRenderer) {
        m_unifiedRenderer->setRenderSettings(settings);
    }
    // 触发重绘
    if (m_pageView) {
        m_pageView->update();
    }
}
// Martin Fowler重构：Extract Method - DPI配置管理
void MainWindow::updateImageProcessorDpiConfig()
{
    if (!m_imageProcessor) {
        return;
    }
    // Martin Fowler重构：使用DpiService统一管理DPI配置
    double cacheDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::CacheGeneration);
    double renderDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::WindowRendering);
    double effectiveDpi = getEffectiveDpi();    // 有效DPI（保护性逻辑）
    DpiConfiguration config(cacheDpi, renderDpi);
    m_imageProcessor->setDpiConfiguration(config);
}
// Martin Fowler重构：DPI配置获取方法
DpiConfiguration MainWindow::getCurrentDpiConfiguration() const
{
    // Martin Fowler重构：使用DpiService获取DPI配置
    double cacheDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::CacheGeneration);
    double renderDpi = DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::WindowRendering);
    DpiConfiguration config(cacheDpi, renderDpi);
    return config;
}
void MainWindow::updateStatusBarSettings(const ProcessingSettings& settings)
{
    // Martin Fowler重构：使用DpiService获取DPI信息
    int panelDpi = settings.standardDPI;
    int systemDpi = static_cast<int>(DpiSvc.getDpiForPurpose(DpiService::DpiPurpose::CacheGeneration));
    int effective = static_cast<int>(getEffectiveDpi());
    QString dpiInfo = (effective < panelDpi)
        ? QString("%1→%2").arg(panelDpi).arg(effective)
        : QString::number(panelDpi);
    // Martin Fowler重构：使用Toast提示DPI警告
    if (effective < panelDpi) {
        // 检查是否已经显示过类似的警告，避免重复提示
        static qint64 lastWarningTime = 0;
        qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
        // 5分钟内不重复显示相同的DPI警告
        if (currentTime - lastWarningTime > 300000) {
            QString message = QString("缓存DPI(%1)低于输出DPI(%2)\n建议提高系统DPI重建缓存")
                              .arg(systemDpi)
                              .arg(panelDpi);
            ToastNotification::showWarning(this, message, 6000);
            lastWarningTime = currentTime;
        }
    }
    QString settingsInfo = QString("DPI: %1 | 页码: %2 | 边距: %3mm")
                           .arg(dpiInfo)
                           .arg(settings.pageNumber.enabled ? "开启" : "关闭")
                           .arg(QString("%1,%2,%3,%4")
                               .arg(settings.margins.top, 0, 'f', 0)
                               .arg(settings.margins.bottom, 0, 'f', 0)
                               .arg(settings.margins.left, 0, 'f', 0)
                               .arg(settings.margins.right, 0, 'f', 0));
    statusBar()->showMessage(settingsInfo, 5000);
    // 当面板DPI超过系统DPI时给出提醒（防抖）
    if (effective < panelDpi) {
        if (!m_toastShown) {
            showToastMessage(tr("面板DPI(%1)高于缓存DPI(%2)\n建议提高系统DPI重建缓存").arg(panelDpi).arg(effective));
            m_toastShown = true;
            QTimer::singleShot(TOAST_MEDIUM_MS, this, [this]() { m_toastShown = false; });
        }
    }
}
// ====== 状态栏相关槽函数实现 ======
void MainWindow::onOneClickExport()
{
    
    // 获取当前文件列表
    if (!m_fileBrowser) {
        showToastMessage("文件浏览器未初始化");
        return;
    }
    
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    if (files.isEmpty()) {
        showToastMessage("请先选择要导出的文件");
        return;
    }
    
    // 自动生成输出路径
    QString outputPath = generateAutoExportPath();
    if (outputPath.isEmpty()) {
        showToastMessage("无法生成输出路径");
        return;
    }
    
    // ✅ KISS原则：直接调用流式导出管理器，无需页面收集
    m_streamingExportManager->startExport(files, m_processingSettings, outputPath);
    
}

void MainWindow::onUpdateRequested()
{

    // 如果有更新信息，创建更新对话框
    if (m_hasUpdateAvailable) {
        // 构建UpdateInfo对象
        VersionManager::UpdateInfo updateInfo;
        updateInfo.latestVersion = VersionManager::Version::fromString(m_serverVersion);
        updateInfo.currentVersion = VersionManager::Version::fromString(m_currentVersion);
        updateInfo.updateUrl = m_downloadUrl;
        updateInfo.updateLog = m_releaseNotes;
        updateInfo.updateSize = m_fileSize; // 使用从API获取的文件大小
        updateInfo.checksumMD5 = m_md5Hash;
        updateInfo.forceUpdate = false;
        updateInfo.hasUpdate = true;

        // 使用showUpdateDialog方法来正确处理信号槽连接
        showUpdateDialog(updateInfo);
    } else {
        // 没有更新时显示提示信息
        QMessageBox::information(this, tr("更新检查"), tr("当前已是最新版本"));
    }

}

QList<QImage> MainWindow::loadAllPagesForFile(const UnifiedFileInfo& constFileInfo)
{
    // === Martin Fowler重构：创建可变副本用于缓存路径记录 ===
    UnifiedFileInfo fileInfo = constFileInfo; // 创建副本
    QList<QImage> pages;
    // 获取文件标识
    QString fileIdentity = FileIdentityManager::getFileIdentity(fileInfo.filePath);
    QString cacheKey = FileIdentityManager::getCacheKey(fileIdentity);
    // 从缓存管理器获取所有页面
    if (m_cacheManager) {
        for (int pageIndex = 0; pageIndex < fileInfo.pageCount; ++pageIndex) {
            QImage pageImage = m_cacheManager->loadFromCache(fileIdentity, pageIndex);
            if (pageImage.isNull()) {
                // 如果不在缓存中，尝试直接从文件加载
                pageImage = loadPageFromFile(fileInfo.filePath, pageIndex);
                if (!pageImage.isNull()) {
                    // === Martin Fowler重构：使用文件级缓存路径保存 ===
                    m_cacheManager->saveToCacheWithFileInfo(fileInfo, pageIndex, pageImage, m_processingSettings.standardDPI);
                }
            }
            if (!pageImage.isNull()) {
                pages.append(pageImage);
            } else {
                // 创建一个占位符图像
                QImage placeholder(800, 600, QImage::Format_RGB32);
                placeholder.fill(QColor(240, 240, 240));
                QPainter painter(&placeholder);
                painter.drawText(placeholder.rect(), Qt::AlignCenter, QString("页面 %1 加载失败").arg(pageIndex + 1));
                pages.append(placeholder);
            }
        }
    }
    return pages;
}
QImage MainWindow::loadPageFromFile(const QString& filePath, int pageIndex)
{
    // 根据文件类型选择不同的加载方式
    if (filePath.toLower().endsWith(".pdf")) {
        // PDF文件处理
        return loadPageFromPDF(filePath, pageIndex);
    } else {
        // 图像文件处理
        return loadPageFromImage(filePath, pageIndex);
    }
}
QImage MainWindow::loadPageFromPDF(const QString& filePath, int pageIndex)
{
    // TODO: 实现PDF页面加载
    // 这里应该使用与主程序相同的PDF渲染逻辑
    return QImage();
}
QImage MainWindow::loadPageFromImage(const QString& filePath, int pageIndex)
{
    // 加载完整图像
    QImageReader reader(filePath);
    if (!reader.canRead()) {
        return QImage();
    }
    QImage fullImage = reader.read();
    if (fullImage.isNull()) {
        return QImage();
    }
    // 使用ImageProcessor来分割图像页面
    if (m_imageProcessor) {
        // 使用单栏模式进行图像分割（导出时通常使用原始分割）
        ImageProcessor::ColumnMode columnMode = LayoutMode::SingleColumn;
        QList<QImage> imagePages = m_imageProcessor->splitImage(fullImage, columnMode);
        if (pageIndex >= 0 && pageIndex < imagePages.size()) {
            return imagePages[pageIndex];
        }
    }
    // 如果分割失败，返回完整图像（对于pageIndex == 0的情况）
    if (pageIndex == 0) {
        return fullImage;
    }
    return QImage();
}
void MainWindow::onExportSettings()
{
    // 直接切换到设置标签
    if (m_rightTabs) {
        m_rightTabs->setCurrentIndex(1); // 设置标签
        // 显示右侧面板（如果隐藏的话）
        if (m_thumbnailDock && !m_thumbnailDock->isVisible()) {
            m_thumbnailDock->show();
        }
        // 设置默认设置到面板
        if (m_settingsWidget) {
            ProcessingSettings defaultSettings = ProcessingSettings::getPreset("标准文档");
            m_settingsWidget->setSettings(defaultSettings);
        }
    }
}
void MainWindow::updateStatusBarFileInfo()
{
    if (!m_statusBarManager || !m_fileBrowser) {
        return;
    }
    int currentIndex = m_fileBrowser->getCurrentIndex();
    int totalFiles = m_fileBrowser->getFileCount();
    // 验证索引有效性，防止显示错误的文件计数
    if (currentIndex >= totalFiles) {
        currentIndex = totalFiles > 0 ? totalFiles - 1 : -1;
        if (currentIndex >= 0) {
            m_fileBrowser->selectFile(currentIndex);  // 修正文件浏览器的选择
        }
    }
    UnifiedFileInfo currentFile;
    if (currentIndex >= 0 && currentIndex < totalFiles) {
        currentFile = m_fileBrowser->getFile(currentIndex);
    }
    if (currentIndex < 0 || totalFiles == 0) {
        setStatusBarFileInfo(0, totalFiles, "无选择");
    } else {
        setStatusBarFileInfo(currentIndex + 1, totalFiles, currentFile.fileName);
    }
    // 更新缓存状态 - 通过状态管理器统一处理
    if (m_appStateManager && m_cacheManager) {
        qint64 cacheSize = m_cacheManager->getCachedActualSize();
        int cacheCount = m_cacheManager->getCacheEntryCount();
        m_appStateManager->updateCacheStatus(cacheSize, cacheCount);
    }
}
void MainWindow::setStatusBarFileInfo(int currentFile, int totalFiles, const QString& fileName)
{
    if (m_appStateManager) {
        // 使用应用状态管理器来统一处理状态更新 - 解决Shotgun Surgery
        m_appStateManager->updateCurrentFileStatus(currentFile - 1, totalFiles, fileName); // currentFile is 1-based, convert to 0-based
    } else {
    }
}
// Martin Fowler重构：ApplicationStateManager集成 - 统一页数管理
void MainWindow::onTotalDisplayPagesChanged(int totalPages)
{
    // 这是一个通知回调，只更新UI显示，不修改数据
    // 避免信号循环：此方法被 totalGlobalPagesChanged 信号触发，不应该再次触发重算
    
    // 直接更新状态栏的总页数显示
    if (m_statusBarManager) {
        m_statusBarManager->updateTotalPages(totalPages);
        
        // === 关键修复：当总页数变为0时，同时重置当前全局页码为0 ===
        if (totalPages == 0) {
            m_statusBarManager->updateCurrentGlobalPage(0, 0);
        }
    }

    // 通知设置面板更新文件大小预估
    if (m_settingsWidget) {
        m_settingsWidget->onPageCountChanged();
    }
}
// 自绘图标方法
QIcon MainWindow::createNavigationIcon() const
{
    QPixmap pixmap(16, 16);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    // 绘制船舵样式的导航图标
    painter.setPen(QPen(QColor(100, 100, 100), 1.5));
    painter.setBrush(QColor(180, 180, 180));
    QPoint center(8, 8);
    int outerRadius = 6;
    int innerRadius = 2;
    // 绘制外圆环
    painter.drawEllipse(center.x() - outerRadius, center.y() - outerRadius,
                       outerRadius * 2, outerRadius * 2);
    // 绘制中心圆
    painter.setBrush(QColor(120, 120, 120));
    painter.drawEllipse(center.x() - innerRadius, center.y() - innerRadius,
                       innerRadius * 2, innerRadius * 2);
    // 绘制8个辐条（船舵的把手）
    painter.setPen(QPen(QColor(100, 100, 100), 2));
    for (int i = 0; i < 8; ++i) {
        double angle = i * M_PI / 4.0;
        int startX = center.x() + (innerRadius + 1) * cos(angle);
        int startY = center.y() + (innerRadius + 1) * sin(angle);
        int endX = center.x() + (outerRadius - 1) * cos(angle);
        int endY = center.y() + (outerRadius - 1) * sin(angle);
        painter.drawLine(startX, startY, endX, endY);
    }
    return QIcon(pixmap);
}
QIcon MainWindow::createSettingsIcon() const
{
    QPixmap pixmap(16, 16);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    // 绘制精细的齿轮图标
    painter.setPen(QPen(QColor(100, 100, 100), 1));
    painter.setBrush(QColor(180, 180, 180));
    QPoint center(8, 8);
    int outerRadius = 6;
    int innerRadius = 4;
    int teethCount = 8;
    // 创建齿轮路径
    QPainterPath gearPath;
    // 绘制齿轮的齿
    for (int i = 0; i < teethCount; ++i) {
        double baseAngle = i * 2.0 * M_PI / teethCount;
        double nextAngle = (i + 1) * 2.0 * M_PI / teethCount;
        // 齿的外边缘点
        double toothAngle = baseAngle + M_PI / teethCount * 0.3;
        double toothAngle2 = baseAngle + M_PI / teethCount * 0.7;
        QPointF outerPoint1(center.x() + outerRadius * cos(toothAngle),
                           center.y() + outerRadius * sin(toothAngle));
        QPointF outerPoint2(center.x() + outerRadius * cos(toothAngle2),
                           center.y() + outerRadius * sin(toothAngle2));
        // 齿根点
        QPointF innerPoint1(center.x() + innerRadius * cos(baseAngle),
                           center.y() + innerRadius * sin(baseAngle));
        QPointF innerPoint2(center.x() + innerRadius * cos(nextAngle),
                           center.y() + innerRadius * sin(nextAngle));
        if (i == 0) {
            gearPath.moveTo(innerPoint1);
        }
        gearPath.lineTo(outerPoint1);
        gearPath.lineTo(outerPoint2);
        gearPath.lineTo(innerPoint2);
    }
    gearPath.closeSubpath();
    painter.fillPath(gearPath, QBrush(QColor(180, 180, 180)));
    painter.drawPath(gearPath);
    // 中心圆孔
    painter.setBrush(Qt::white);
    painter.setPen(QPen(QColor(100, 100, 100), 1));
    painter.drawEllipse(center.x() - 2, center.y() - 2, 4, 4);
    return QIcon(pixmap);
}
QIcon MainWindow::createInfoIcon() const
{
    QPixmap pixmap(16, 16);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    // 绘制信息图标（圆形内带i）
    painter.setPen(QPen(QColor(70, 130, 180), 1.5));
    painter.setBrush(QColor(173, 216, 230));
    // 外圆
    painter.drawEllipse(2, 2, 12, 12);
    // 绘制字母i
    painter.setPen(QPen(QColor(70, 130, 180), 2));
    painter.setFont(QFont("Arial", 8, QFont::Bold));
    painter.drawText(QRect(2, 2, 12, 12), Qt::AlignCenter, "i");
    return QIcon(pixmap);
}

QIcon MainWindow::createSplitPanelIcon(bool leftActive) const
{
    QPixmap pixmap(16, 16);
    pixmap.fill(Qt::transparent);
    QPainter painter(&pixmap);
    painter.setRenderHint(QPainter::Antialiasing);
    
    // 绘制分割面板图标 - 确保两个按钮大小和比例完全一致
    QRect iconRect(2, 3, 12, 10);
    
    // 使用50:50的比例，确保黑白区域大小一致
    int leftWidth = iconRect.width() / 2;  // 左侧宽度：6像素
    int rightWidth = iconRect.width() - leftWidth;  // 右侧宽度：6像素
    
    if (leftActive) {
        // 文件列表按钮：左侧深灰色（激活），右侧浅灰色
        painter.fillRect(iconRect.left(), iconRect.top(), 
                        leftWidth, iconRect.height(), 
                        QColor(51, 51, 51));  // 深灰色 #333333
        painter.fillRect(iconRect.left() + leftWidth, iconRect.top(), 
                        rightWidth, iconRect.height(), 
                        QColor(221, 221, 221));  // 浅灰色 #DDDDDD
    } else {
        // 预览面板按钮：左侧浅灰色，右侧深灰色（激活）
        painter.fillRect(iconRect.left(), iconRect.top(), 
                        leftWidth, iconRect.height(), 
                        QColor(221, 221, 221));  // 浅灰色 #DDDDDD
        painter.fillRect(iconRect.left() + leftWidth, iconRect.top(), 
                        rightWidth, iconRect.height(), 
                        QColor(51, 51, 51));  // 深灰色 #333333
    }
    
    // 添加边框
    painter.setPen(QPen(QColor(150, 150, 150), 1));
    painter.drawRect(iconRect);
    
    return QIcon(pixmap);
}

// ============================================================================
// 重构：系统配置管理方法
// Martin Fowler: Extract Method, Encapsulate Field
// ============================================================================
void MainWindow::loadSystemConfig()
{
    // Martin Fowler重构：使用统一的配置管理器
    // 确保配置管理器已初始化
    if (!ConfigMgr.isInitialized()) {
        ConfigMgr.reloadConfig();
    }
    // 从配置管理器获取配置
    m_systemConfig = ConfigMgr.getConfig();
    // 应用缓存目录配置
    if (m_cacheManager) {
        m_cacheManager->setCacheDirectory(m_systemConfig.cacheDirectory);
        // 启动空间监控机制
        m_cacheManager->startSpaceMonitoring(m_systemConfig.spaceThresholdGB, 60000);
    }
    // 连接配置变更信号，以便实时更新
    connect(&ConfigMgr, &SystemConfigManager::configChanged,
            this, [this](const SystemConfig& oldConfig, const SystemConfig& newConfig) {
                m_systemConfig = newConfig;
                // 可以在这里添加其他需要响应配置变更的逻辑
            });
}
void MainWindow::saveSystemConfig()
{
    // Martin Fowler重构：使用配置管理器保存
    ConfigMgr.updateConfig(m_systemConfig);
}
void MainWindow::applySystemConfig(const SystemConfig& config)
{
    
    // Martin Fowler重构：在更新前保存旧配置用于比较
    SystemConfig oldConfig = m_systemConfig;
    // Martin Fowler重构：使用配置管理器统一更新配置
    // 配置管理器会自动保存并发出变更信号
    ConfigMgr.updateConfig(config);
    
    // 检查是否有文件需要处理
    int fileCount = m_fileBrowser ? m_fileBrowser->getFileCount() : 0;
    
    if (fileCount == 0) {
        // 仅应用不需要缓存重建的配置项
        // 应用缓存目录配置
        if (m_cacheManager && config.cacheDirectory != m_systemConfig.cacheDirectory) {
            m_cacheManager->setCacheDirectory(config.cacheDirectory);
        }
        // 启动或更新空间监控机制
        if (m_cacheManager) {
            m_cacheManager->startSpaceMonitoring(config.spaceThresholdGB, 60000);
        }
        // 更新ImageProcessor的DPI配置
        updateImageProcessorDpiConfig();
        return; // 直接返回，不进行缓存重建
    }
    
    // 有文件时才进行缓存重建判断
    
    // Martin Fowler重构：使用CacheRebuildManager统一管理缓存重建
    if (!m_cacheRebuildManager) {
        m_cacheRebuildManager = std::make_unique<CacheRebuildManager>(this);
        // 连接重建完成信号到处理槽
        connect(m_cacheRebuildManager.get(), &CacheRebuildManager::rebuildCompleted,
                this, [this]() {
                    rebuildUsingExistingPipeline();
                });
        // 连接重建进度信号到Toast提示
        connect(m_cacheRebuildManager.get(), &CacheRebuildManager::rebuildProgress,
                this, [this](const QString& message) {
                    if (!message.isEmpty()) {
                        showToastMessage(message);
                    }
                });
    }
    // 分析配置变更（使用保存的旧配置进行比较）
    bool needsRebuild = m_cacheRebuildManager->analyzeConfigChange(oldConfig, config);
    
    if (needsRebuild) {
        // 保存当前状态以备重建
        QString currentFilePath;
        if (m_fileBrowser && m_fileBrowser->getCurrentIndex() >= 0) {
            currentFilePath = m_fileBrowser->getFile(m_fileBrowser->getCurrentIndex()).filePath;
        }
        // 设置文件列表和当前文件
        if (m_fileBrowser) {
            m_cacheRebuildManager->setFileList(m_fileBrowser->getFiles());
        }
        m_cacheRebuildManager->setCurrentFilePath(currentFilePath);
        // 执行重建
        m_cacheRebuildManager->executeCacheRebuild();
    } else {
        // 即使不需要重建，也要应用其他配置
        // 应用缓存目录配置（如果有变化，但不触发重建）
        if (m_cacheManager && config.cacheDirectory != m_systemConfig.cacheDirectory) {
            m_cacheManager->setCacheDirectory(config.cacheDirectory);
        }
        // 启动或更新空间监控机制
        if (m_cacheManager) {
            m_cacheManager->startSpaceMonitoring(config.spaceThresholdGB, 60000);
        }
        // 更新ImageProcessor的DPI配置
        updateImageProcessorDpiConfig();
    }
    
    // 如果内存策略改变，立即进行内存管理
    if (config.memoryStrategy != m_systemConfig.memoryStrategy) {
        int currentPage = m_pageView ? m_pageView->currentPage() : 0;
        managePagesMemory(currentPage);
    }
    
    // 本地配置也会通过配置变更信号自动更新（见loadSystemConfig中的connect）
}
void MainWindow::startCacheRebuildProcess(const ConfigImpactDetector::RebuildRequirement& requirement)
{
    // 检查是否有文件需要重建缓存
    if (m_fileBrowser && m_fileBrowser->getFileCount() > 0) {
        if (requirement.isDPIOnly()) {
            // 仅DPI变更：只需要更新ImageProcessor的DPI配置，重新处理当前文件
            updateCurrentFileDPI();
        } else {
            // 缓存目录变更或两者都变更：需要重建所有缓存
            rebuildAllFilesCache();
        }
    } else {
    }
}
void MainWindow::updateCurrentFileDPI()
{
    // 获取当前文件
    int currentFileIndex = m_fileBrowser->getCurrentIndex();
    if (currentFileIndex < 0) {
        return;
    }
    UnifiedFileInfo currentFile = m_fileBrowser->getFile(currentFileIndex);
    QString currentFilePath = currentFile.filePath;
    if (currentFilePath.isEmpty() || !QFile::exists(currentFilePath)) {
        return;
    }
    // 更新ImageProcessor的DPI配置
    if (m_imageProcessor) {
        m_imageProcessor->setDpiConfiguration(getCurrentDpiConfiguration());
    }
    // 清除当前文件的缓存并重新加载
    if (m_cacheManager) {
        m_cacheManager->deleteCacheEntry(currentFile.fileIdentity);
    }
    // 重新加载当前文件以应用新的DPI设置
    QTimer::singleShot(100, [this, currentFilePath]() {
        loadFileFromCache(currentFilePath);
    });
}
void MainWindow::rebuildAllFilesCache()
{
    if (!m_fileBrowser || m_fileBrowser->getFileCount() == 0) {
        return;
    }
    // 获取当前文件信息，以便重建完成后恢复
    int currentFileIndex = m_fileBrowser->getCurrentIndex();
    QString currentFilePath;
    if (currentFileIndex >= 0) {
        UnifiedFileInfo currentFile = m_fileBrowser->getFile(currentFileIndex);
        currentFilePath = currentFile.filePath;
    }
    // 重建所有文件的缓存
    int totalFiles = m_fileBrowser->getFileCount();
    int processedCount = 0;
    // 使用现有的文件处理机制，集成进度UI
    for (int i = 0; i < totalFiles; ++i) {
        UnifiedFileInfo fileInfo = m_fileBrowser->getFile(i);
        QString filePath = fileInfo.filePath;
        if (filePath.isEmpty() || !QFile::exists(filePath)) {
            continue;
        }
        try {
            // 更新文件状态为处理中
            if (m_fileBrowser) {
                m_fileBrowser->updateFileProgress(i, 0, "正在重建缓存...");
            }
            // 使用FileProcessWorker重新处理文件，连接进度信号
            DpiConfiguration dpiConfig = getCurrentDpiConfiguration();
            FileProcessWorker* worker = new FileProcessWorker(i, filePath, dpiConfig, this);
            // 连接进度更新信号到文件列表UI
            connect(worker, &FileProcessWorker::progressUpdated, this, [this](int fileIndex, const UnifiedFileInfo& info) {
                if (m_fileBrowser) {
                    m_fileBrowser->updateFileProgress(fileIndex, info.progress, "正在重建缓存...");
                }
            });
            // 创建本地事件循环等待处理完成
            QEventLoop loop;
            QTimer timeoutTimer;
            timeoutTimer.setSingleShot(true);
            timeoutTimer.setInterval(60000); // 60秒超时，给缓存重建更多时间
            bool processingSuccess = false;
            connect(worker, &FileProcessWorker::processingFinished, [&](int fileIndex, bool success) {
                processingSuccess = success;
                // 更新文件状态
                if (m_fileBrowser) {
                    if (success) {
                        m_fileBrowser->updateFileProgress(fileIndex, 100, "缓存重建完成");
                    } else {
                        m_fileBrowser->updateFileProgress(fileIndex, 0, "缓存重建失败");
                    }
                }
                loop.quit();
            });
            connect(&timeoutTimer, &QTimer::timeout, [&]() {
                if (m_fileBrowser) {
                    m_fileBrowser->updateFileProgress(i, 0, "缓存重建超时");
                }
                loop.quit();
            });
            // 启动处理和超时计时器
            QThreadPool::globalInstance()->start(worker);
            timeoutTimer.start();
            // 等待处理完成，保持UI响应
            while (loop.isRunning()) {
                QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                QThread::msleep(50); // 短暂休眠避免CPU占用过高
            }
            if (timeoutTimer.isActive()) {
                timeoutTimer.stop();
            }
            if (processingSuccess) {
                processedCount++;
            } else {
            }
        } catch (const std::exception& e) {
            if (m_fileBrowser) {
                m_fileBrowser->updateFileProgress(i, 0, "缓存重建异常");
            }
        } catch (...) {
            if (m_fileBrowser) {
                m_fileBrowser->updateFileProgress(i, 0, "缓存重建异常");
            }
        }
    }
    // 延迟清理进度显示，让用户看到完成状态
    QTimer::singleShot(2000, [this]() {
        // 清理所有文件的进度显示
        if (m_fileBrowser) {
            for (int i = 0; i < m_fileBrowser->getFileCount(); ++i) {
                m_fileBrowser->updateFileProgress(i, -1, ""); // -1表示清除进度显示
            }
        }
    });
    // 如果有当前打开的文件，重新加载它以应用新的缓存
    if (!currentFilePath.isEmpty() && QFile::exists(currentFilePath)) {
        // 延迟重新加载，确保所有缓存处理完成
        QTimer::singleShot(1000, [this, currentFilePath]() {
            loadFileFromCache(currentFilePath);
        });
    }
}
// Martin Fowler重构：使用现有文件处理管道重建缓存
void MainWindow::rebuildUsingExistingPipeline()
{
    if (!m_fileBrowser || m_fileBrowser->getFileCount() == 0) {
        return;
    }
    // 保存当前文件信息，以便重建完成后恢复
    int currentFileIndex = m_fileBrowser->getCurrentIndex();
    QString currentFilePath;
    if (currentFileIndex >= 0) {
        UnifiedFileInfo currentFile = m_fileBrowser->getFile(currentFileIndex);
        currentFilePath = currentFile.filePath;
    }
    // 关键：复用现有的文件处理管道
    // 这与文件拖拽的处理流程完全一致
    startFileProcessing();
    // 延迟恢复当前文件，确保所有文件处理完成
    if (!currentFilePath.isEmpty() && QFile::exists(currentFilePath)) {
        QTimer::singleShot(1000, [this, currentFilePath]() {
            loadFileFromCache(currentFilePath);
        });
    }
}
// 页码实时预览槽函数实现
void MainWindow::onPageNumberPositionPreviewChanged(const QPointF& position)
{
    // 在拖动过程中，使用临时位置渲染预览
    // 更新页面视图以显示预览
    if (m_pageView) {
        // 需要将SmartPageNumberSelector中的坐标转换到实际页面坐标
        // SmartPageNumberSelector使用A4比例页面，需要映射到实际页面尺寸
        // 获取当前页面的实际尺寸
        if (m_pages.isEmpty() || m_pageView->currentPage() < 0 || m_pageView->currentPage() >= m_pages.size()) {
            return;
        }
        QImage currentPage = m_pages[m_pageView->currentPage()];
        if (currentPage.isNull()) {
            return;
        }
        // 获取SmartPageNumberSelector的页面尺寸（A4比例）
        auto* smartSelector = m_settingsWidget->getSmartPageNumberSelector();
        if (!smartSelector) {
            return;
        }
        // 计算坐标转换比例
        // 从A4页面坐标转换到实际页面坐标
        QRectF selectorPageRect = smartSelector->getPageRect();
        QSizeF actualPageSize = currentPage.size();
        // position是相对于整个SmartPageNumberSelector组件的坐标，需要先转换为相对于页面的坐标
        QPointF relativePagePos(position.x() - selectorPageRect.left(),
                               position.y() - selectorPageRect.top());
        // 计算转换比例（从页面内部坐标到实际页面坐标）
        double scaleX = actualPageSize.width() / selectorPageRect.width();
        double scaleY = actualPageSize.height() / selectorPageRect.height();
        // 转换坐标到实际页面坐标
        QPointF actualPosition(relativePagePos.x() * scaleX, relativePagePos.y() * scaleY);
        // 只有在当前确实是自定义位置时才应用预览
        if (m_processingSettings.pageNumber.position == PagePositionSystem::Position::Custom) {
            // 应用转换后的预览位置
            ProcessingSettings::PageNumberSettings previewSettings = m_processingSettings.pageNumber;
            // 使用网格系统设置位置
            // TODO: 如需要的话，将像素位置转换为网格状态
            // previewSettings.gridState = GridPageNumberSystem::GridState::fromMillimeterOffset(...);
            // 应用预览设置到主处理设置，确保预览效果可见
            m_processingSettings.pageNumber = previewSettings;
        } else {
            return;
        }
        if (m_unifiedRenderer) {
            m_unifiedRenderer->setRenderSettings(m_processingSettings);
        }
        // 使用防抖机制避免频繁重绘
        if (m_pageNumberPreviewTimer) {
            m_pageNumberPreviewTimer->stop();
        } else {
            m_pageNumberPreviewTimer = new QTimer(this);
            m_pageNumberPreviewTimer->setSingleShot(true);
            m_pageNumberPreviewTimer->setInterval(50); // 50ms防抖，预览可以更快响应
        }
        
        // 连接定时器到预览更新方法
        disconnect(m_pageNumberPreviewTimer, &QTimer::timeout, nullptr, nullptr);
        connect(m_pageNumberPreviewTimer, &QTimer::timeout, this, [this]() {
            if (m_pageView) {
                m_pageView->forceUpdatePageNumbers();
            }
        });
        m_pageNumberPreviewTimer->start();
    }
}
void MainWindow::onPageNumberSettingsChanged(const ProcessingSettings::PageNumberSettings& settings)
{
    // 页码设置最终确定后，更新到处理设置中
    m_processingSettings.pageNumber = settings;
    // 更新渲染器设置
    if (m_unifiedRenderer) {
        m_unifiedRenderer->setRenderSettings(m_processingSettings);
    }
    // 使用防抖机制避免多次重绘
    if (m_pageView) {
        // 停止之前的定时器
        if (m_pageNumberUpdateTimer) {
            m_pageNumberUpdateTimer->stop();
        } else {
            m_pageNumberUpdateTimer = new QTimer(this);
            m_pageNumberUpdateTimer->setSingleShot(true);
            m_pageNumberUpdateTimer->setInterval(100); // 100ms防抖
        }
        // 连接定时器到更新方法
        disconnect(m_pageNumberUpdateTimer, &QTimer::timeout, nullptr, nullptr);
        connect(m_pageNumberUpdateTimer, &QTimer::timeout, this, [this]() {
            if (m_pageView) {
                m_pageView->forceUpdatePageNumbers();
            }
        });
        m_pageNumberUpdateTimer->start();
    }
    // 保存设置到配置文件
    
    ConfigManager::setProcessingSettings(m_processingSettings.toJsonString());
}
// === Martin Fowler重构：全局页码连续性支持 ===
void MainWindow::switchToFileWithContinuousPaging(const QString& fileIdentity, const QString& targetPage)
{
    if (!m_fileBrowser) {
        return;
    }
    // 1. 获取文件信息
    QList<UnifiedFileInfo> files = m_fileBrowser->getFiles();
    const UnifiedFileInfo* fileInfo = nullptr;
    int fileIndex = -1;
    for (int i = 0; i < files.size(); ++i) {
        if (files[i].fileIdentity == fileIdentity) {
            fileInfo = &files[i];
            fileIndex = i;
            break;
        }
    }
    if (!fileInfo) {
        return;
    }
    // 2. 获取文件的全局起始页码
    GlobalPageManager& globalPageManager = GlobalPageManager::instance();
    int globalStartPage = globalPageManager.getFileStartPage(fileIdentity);
    // 如果全局起始页码无效，首先初始化GlobalPageManager的文件信息
    if (globalStartPage <= 0) {
        // 确保文件信息已在GlobalPageManager中注册
        globalPageManager.updateFileInfo(fileIdentity, fileInfo->pageCount);
        // 重新计算页码映射
        globalPageManager.recalculatePageMappings();
        // 再次获取起始页码
        globalStartPage = globalPageManager.getFileStartPage(fileIdentity);
        if (globalStartPage <= 0) {
            loadFileFromCache(fileInfo->filePath);
            return;
        }
    }
    // 3. 计算目标全局页码
    int targetGlobalPage = globalStartPage;
    if (!targetPage.isEmpty()) {
        // 如果指定了目标页码，需要转换为全局页码
        bool ok;
        int localPage = targetPage.toInt(&ok) - 1; // 转换为0-based索引
        if (ok && localPage >= 0) {
            targetGlobalPage = globalPageManager.convertToGlobalPage(fileIdentity, localPage);
        }
    }
    // 4. 更新GlobalPageManager的当前页码
    globalPageManager.setCurrentGlobalPage(targetGlobalPage);
    // 5. 注意：文件已经被选中，不需要再次选择以避免递归调用
    // 文件选择流程已经完成，现在只需要处理页码连续性
    // 6. 加载文件内容
    QString filePath = fileInfo->filePath;
    if (!filePath.isEmpty()) {
        loadFileFromCache(filePath);
        // 7. 设置文件的全局起始页码（如果文件已加载）
        if (m_pageView && !m_pages.isEmpty()) {
            m_pageView->setFileGlobalStartPage(globalStartPage);
            // 8. 跳转到目标页码
            if (targetGlobalPage != globalStartPage) {
                m_pageView->setGlobalCurrentPage(targetGlobalPage);
            }
        }
    }
}
void MainWindow::onGlobalPageChanged(int globalPage)
{
    // 如果当前PageView有页面，尝试设置全局页码
    if (m_pageView && !m_pages.isEmpty()) {
        if (!m_pageView->setGlobalCurrentPage(globalPage)) {
            // 如果设置失败，可能需要切换文件
            // 这里可以添加文件切换逻辑
        }
    }
}
void MainWindow::onPageMappingsChanged()
{
    // 重新计算当前文件的全局起始页码
    if (m_pageView && !m_currentFileHash.isEmpty()) {
        GlobalPageManager& globalPageManager = GlobalPageManager::instance();
        int newStartPage = globalPageManager.getFileStartPage(m_currentFileHash);
        if (newStartPage > 0) {
            m_pageView->setFileGlobalStartPage(newStartPage);
            // 更新当前全局页码
            int currentGlobalPage = m_pageView->getGlobalCurrentPage();
            globalPageManager.setCurrentGlobalPage(currentGlobalPage);
        }
    }
}

// 设置固定的窗口布局
void MainWindow::setupFixedWindowLayout()
{
    // 设置窗口大小为屏幕的2/3并居中
    QScreen *screen = QGuiApplication::primaryScreen();
    QRect screenGeometry = screen->availableGeometry();

    int windowWidth = screenGeometry.width() * 2 / 3;
    int windowHeight = screenGeometry.height() * 2 / 3;
    int windowX = (screenGeometry.width() - windowWidth) / 2;
    int windowY = (screenGeometry.height() - windowHeight) / 2;

    setGeometry(windowX, windowY, windowWidth, windowHeight);

    // 设置文件列表窗口宽度为窗口宽度的1/3但不小于100px
    // 注意：这个设置需要在dock widgets创建之后进行，所以我们将此逻辑移到setupUI的末尾
}

QString MainWindow::generateAutoExportPath() const
{
    // 使用PathManager获取标准PDF导出目录
    QString exportDir = PathManager::getPdfExportDirectory();
    
    // 确保目录存在
    QDir dir(exportDir);
    if (!dir.exists()) {
        dir.mkpath(".");
    }
    
    // 生成当前日期字符串 (MMDD格式)
    QDateTime now = QDateTime::currentDateTime();
    QString dateStr = now.toString("MMdd");
    
    // 生成基础文件名
    QString baseFileName = QString("材料-%1-01.pdf").arg(dateStr);
    QString fullPath = dir.absoluteFilePath(baseFileName);
    
    // 检查文件是否存在，如果存在则递增编号
    int counter = 1;
    while (QFile::exists(fullPath)) {
        counter++;
        QString fileName = QString("材料-%1-%2.pdf").arg(dateStr).arg(counter, 2, 10, QChar('0'));
        fullPath = dir.absoluteFilePath(fileName);
    }
    
    return fullPath;
}



// === 版本管理相关实现 ===
void MainWindow::initializeVersionInfo()
{

    // 获取当前版本
    m_currentVersion = ConfigManager::getCurrentVersion();
    m_serverVersion = "检查中...";  // 初始状态

    // 更新状态栏版本信息
    if (m_statusBarManager) {
        m_statusBarManager->updateVersionInfo(m_currentVersion, m_serverVersion);
    }

    // 注释：移除独立的UpdateManager检查，统一使用ApiManager心跳检查

}

void MainWindow::updateVersionDisplay()
{
    // 更新状态栏版本信息
    if (m_statusBarManager) {
        m_statusBarManager->updateVersionInfo(m_currentVersion, m_serverVersion);
    }
}

void MainWindow::updateWelcomeMessage()
{
    QString welcomeText = getWelcomeVersionMessage();

    // 如果当前没有文件打开，显示版本信息
    if (m_pages.isEmpty()) {
        // 在PageView中显示欢迎信息
        if (m_pageView) {
            m_pageView->setWelcomeMessage(welcomeText);
        }
    }
}

QString MainWindow::getWelcomeVersionMessage()
{
    return tr("当前版本 %1，服务器版本 %2")
           .arg(m_currentVersion)
           .arg(m_serverVersion);
}

void MainWindow::onUpdateAvailable(const VersionManager::UpdateInfo& info)
{

    // 通知系统托盘管理器
    if (m_systemTrayManager) {
        m_systemTrayManager->onUpdateAvailable(info);
    }

    // 显示更新对话框
    showUpdateDialog(info);
}

void MainWindow::showUpdateDialog(const VersionManager::UpdateInfo& info)
{

    // 创建并显示更新对话框
    UpdateDialog* updateDialog = new UpdateDialog(info, this);

    // 连接UpdateDialog的信号
    // 如果UpdateDialog来自AboutDialog（通过UpdateChecker），则使用UpdateChecker下载
    // 如果来自UpdateManager自动检查，则使用UpdateManager下载
    connect(updateDialog, &UpdateDialog::requestStartDownload, this, [this, info, updateDialog]() {

        if (m_updateChecker && !info.updateUrl.isEmpty()) {

            // 连接UpdateChecker信号到UpdateDialog
            connect(m_updateChecker, &UpdateChecker::downloadProgress, updateDialog,
                    [updateDialog](qint64 received, qint64 total) {
                int progress = total > 0 ? (int)((received * 100) / total) : 0;
                updateDialog->onDownloadProgress(progress, received, total);
            });
            connect(m_updateChecker, &UpdateChecker::downloadFinished, updateDialog, &UpdateDialog::onDownloadFinished);
            connect(m_updateChecker, &UpdateChecker::checkError, updateDialog, &UpdateDialog::onDownloadError);

            m_updateChecker->downloadUpdate(info.updateUrl, info.checksumMD5);
        } else if (m_updateManager) {
            m_updateManager->startUpdate();
        } else {
        }

    });

    connect(updateDialog, &UpdateDialog::requestPauseDownload, this, [this]() {
        if (m_updateManager) {
            m_updateManager->pauseDownload();
        }
    });

    // 如果没有UpdateChecker连接，则连接UpdateManager（向后兼容）
    if (info.updateUrl.isEmpty()) {
        connect(m_updateManager, &UpdateManager::downloadProgress, updateDialog, &UpdateDialog::onDownloadProgress);
        connect(m_updateManager, &UpdateManager::downloadFinished, updateDialog, &UpdateDialog::onDownloadFinished);
        connect(m_updateManager, &UpdateManager::downloadError, updateDialog, &UpdateDialog::onDownloadError);
    }

    // 显示对话框
    int result = updateDialog->exec();

    // 处理用户选择
    switch (result) {
    case QDialog::Accepted:
        // 用户点击了"立即更新"或对话框的关闭
        break;
    case QDialog::Rejected:
        // 用户点击了"稍后提醒"或对话框的取消
        break;
    default:
        break;
    }

    // 清理对话框
    updateDialog->deleteLater();
}

void MainWindow::onUpdateFinished(const QString& filePath)
{
    // 通知系统托盘管理器
    if (m_systemTrayManager) {
        m_systemTrayManager->onDownloadFinished(filePath);
    }

    if (!filePath.isEmpty()) {
        QMessageBox::information(this, tr("更新完成"), tr("更新包已成功下载，请按照提示完成安装。"));
    } else {
    }
}

void MainWindow::onUpdateProgress(int progress, qint64 received, qint64 total)
{
    // 通知系统托盘管理器
    if (m_systemTrayManager) {
        m_systemTrayManager->onDownloadProgress(progress, received, total);
    }

    // 可以在这里更新状态栏显示下载进度
}

void MainWindow::onVersionInfoReceived(const QString& latestVersion, const QString& downloadUrl, const QString& releaseNotes, const QString& md5Hash)
{

    // 比较版本号，判断是否需要更新
    VersionManager::Version currentVer = VersionManager::Version::fromString(m_currentVersion);
    VersionManager::Version latestVer = VersionManager::Version::fromString(latestVersion);

    if (latestVer.isNewerThan(currentVer)) {

        // 存储版本信息
        m_serverVersion = latestVersion;
        m_downloadUrl = downloadUrl;
        m_releaseNotes = releaseNotes;
        m_md5Hash = md5Hash;
        m_hasUpdateAvailable = true;

        // 更新状态栏显示
        updateVersionDisplay();

        // 创建UpdateInfo对象并显示更新对话框
        VersionManager::UpdateInfo updateInfo;
        updateInfo.latestVersion = latestVer;
        updateInfo.updateUrl = downloadUrl;
        updateInfo.updateLog = releaseNotes;
        updateInfo.checksumMD5 = md5Hash;
        updateInfo.forceUpdate = false;
        updateInfo.hasUpdate = true;

        // 更新状态栏更新按钮状态
        if (m_statusBarManager) {
            m_statusBarManager->setUpdateButtonState(true);
        }
    } else {
        m_hasUpdateAvailable = false;
        updateVersionDisplay();

        // 更新状态栏更新按钮状态为禁用
        if (m_statusBarManager) {
            m_statusBarManager->setUpdateButtonState(false);
        }
    }
}

void MainWindow::onTokenExpired()
{

    // 停止心跳
    if (m_apiManager) {
        m_apiManager->stopHeartbeat();
    }

    // 清除Token相关认证信息，但保留用户邮箱和密码
    ConfigManager::setAuthToken("");
    ConfigManager::clearSubscriptionInfo();
    // 注意：保留邮箱和密码，方便用户重新登录

    // 更新用户状态为试用用户
    LoginDialog::updateUserStatus(true);

    // 更新UI状态
    updateLoginAction();

    // 更新登录状态指示器（失效）
    updateLoginStatusIndicator(false);

    // 显示Token过期提示
    showToastMessage(tr("登录已过期，已自动切换为试用模式。如需继续使用高级功能，请重新登录。"));

}

void MainWindow::onHeartbeatError(const QString& error)
{

    // 心跳错误通常表示网络问题或服务器临时不可用
    // 不立即退出登录，而是记录错误并在网络恢复时继续
    m_heartbeatErrorCount++;
    m_consecutiveHeartbeatFailures++;


    // 如果连续多次心跳失败，可能需要提示用户
    if (m_heartbeatErrorCount >= 3) {

        // 每3次失败显示一次提示，避免频繁打扰用户
        if (m_heartbeatErrorCount % 3 == 0) {
            showToastMessage(tr("网络连接不稳定，某些功能可能受到影响"));
        }
    }

    // 连续失败3次后，强制重新登录
    if (m_consecutiveHeartbeatFailures >= 3) {

        // 停止心跳
        if (m_apiManager) {
            m_apiManager->stopHeartbeat();
        }

        // 清除Token相关认证信息，但保留用户邮箱和密码
        ConfigManager::setAuthToken("");
        ConfigManager::clearSubscriptionInfo();
        // 注意：保留邮箱和密码，方便用户重新登录

        // 更新用户状态为试用用户
        LoginDialog::updateUserStatus(true);

        // 更新UI状态
        updateLoginAction();

        // 更新登录状态指示器（失效）
        updateLoginStatusIndicator(false);

        // 显示强制重新登录提示
        showToastMessage(tr("连续验证失败，请重新登录"));

        // 重置计数器
        m_consecutiveHeartbeatFailures = 0;
    }

    // 当心跳恢复时重置计数器（通过heartbeatSuccess信号处理）
}

void MainWindow::onHeartbeatSuccess()
{
    // 心跳成功时重置错误计数器
    if (m_heartbeatErrorCount > 0 || m_consecutiveHeartbeatFailures > 0) {
        m_heartbeatErrorCount = 0;
        m_consecutiveHeartbeatFailures = 0;
    }

    // 如果当前有有效Token，更新登录状态指示器为有效
    if (m_apiManager && m_apiManager->hasValidToken()) {
        updateLoginStatusIndicator(true);
    }
}

void MainWindow::onDeviceNotFound()
{

    // 停止心跳
    if (m_apiManager) {
        m_apiManager->stopHeartbeat();
    }

    // 更新用户状态为试用用户
    LoginDialog::updateUserStatus(true);

    // 更新UI状态
    updateLoginAction();

    // 更新登录状态指示器（失效）
    updateLoginStatusIndicator(false);

    // 显示设备失效提示
    showToastMessage(tr("设备已失效，请重新登录"));

}

void MainWindow::onNetworkError(const QString& error)
{

    // 网络错误可能是临时的，记录但不立即退出登录
    // 用户可以选择继续使用离线功能
    showToastMessage(tr("网络连接错误：%1").arg(error));
}

void MainWindow::updateLoginStatusIndicator(bool isActive)
{
    if (m_statusBarManager) {
        m_statusBarManager->updateLoginStatus(isActive);
    }
}

void MainWindow::handleUpdateError(const QString& error)
{
    // 通知系统托盘管理器
    if (m_systemTrayManager) {
        m_systemTrayManager->onDownloadError(error);
    }


    QMessageBox::StandardButton reply = QMessageBox::warning(this,
        tr("更新失败"),
        tr("更新过程中出现错误：%1\n\n是否要手动下载更新包？").arg(error),
        QMessageBox::Yes | QMessageBox::No);

    if (reply == QMessageBox::Yes) {
        // 打开下载目录或提供手动下载链接
        QString downloadUrl = m_updateManager ? m_updateManager->getUpdateInfo().updateUrl : "";
        if (!downloadUrl.isEmpty()) {
            QDesktopServices::openUrl(QUrl(downloadUrl));
        }
    }
}

// === 安全防护系统初始化 ===
void MainWindow::initializeSecuritySystems()
{
    // 1. 初始化代码混淆系统
    CodeObfuscation::instance().initializeObfuscation();
    
    // 2. 初始化高级保护系统
    AdvancedProtection::instance().initializeProtection();
    
    // 3. 动态水印系统自动初始化
    DynamicWatermark::instance();
    
    // 4. 连接安全事件处理信号
    connect(&AdvancedProtection::instance(), &AdvancedProtection::protectionTriggered,
            this, &MainWindow::handleSecurityViolation);
    
    connect(&DynamicWatermark::instance(), &DynamicWatermark::tamperingDetected,
            this, &MainWindow::handleTamperingAttempt);
    
    connect(&CodeObfuscation::instance(), &CodeObfuscation::integrityViolationDetected,
            this, &MainWindow::handleIntegrityViolation);
    
}

// 安全事件处理函数
void MainWindow::handleSecurityViolation(const QString& reason)
{
    qWarning() << "[Security] 安全违规检测: " << reason;
    
    // 记录到日志
    if (m_logStream) {
        *m_logStream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
                     << " [Security] 安全违规: " << reason << "\n";
        m_logStream->flush();
    }
    
    // 可选：显示警告或采取对抗措施
    // 注意：不要直接弹窗，避免给用户不好的体验
}

void MainWindow::handleTamperingAttempt(const QString& details)
{
    qWarning() << "[Security] 检测到篡改尝试: " << details;
    
    // 记录到日志
    if (m_logStream) {
        *m_logStream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
                     << " [Security] 篡改尝试: " << details << "\n";
        m_logStream->flush();
    }
    
    // 强化安全措施：可以选择增强水印
}

void MainWindow::handleIntegrityViolation()
{
    qWarning() << "[Security] 代码完整性违规检测";
    
    // 记录到日志
    if (m_logStream) {
        *m_logStream << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")
                     << " [Security] 完整性违规\n";
        m_logStream->flush();
    }
    
    // 可选：禁用关键功能或退出
}


